Substituir Caracteres

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
elciodba
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 76
Registrado em: Sex, 31 Out 2008 4:30 pm
Localização: belo horizonte-mg

Pessoal,

Preciso de uma função onde eu pego um caracter especial no registro e entre esse caracter eu quero
enviar uma ação.

por exemplo

jose *silva* reis gostaria que quando estiver entre os '*' ficasse maiusculo

Selecionar tudo

jose SILVA reis 
ou

Selecionar tudo

antonio maria *neves*
antonio maria NEVES
alguém conhece uma maneira ou alguma função que faça isso?

obrigado


Marcos
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

talvez tenha que implementar uma funcao em plsql,

usando INSTR, UPPER...
Avatar do usuário
Bogos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 20
Registrado em: Ter, 06 Jul 2010 8:58 am
Localização: Americana / SP
Contato:

A última resposta do tópico já foi à um tempo considerável mas talvez não tenha resolvido o problema.

@diegolenhardt
Já precisei fazer isso para inserir caracteres especiais em um arquivo texto, ficou bem estilo BBCode. Resolvi o problema facilmente com uma função utilizando expressões regulares, mais precisamente regexp_replace onde você pode utilizar de "retrovisores" para fazer o que você precisar.

Você pode montar uma tabela com o caracter especial (no seu ex. o *) ou como BBCode, exemplo [codigo]texto[/codigo] fazendo relação com uma função do Oracle (upper, lower, etc.). Depois só rodar um loop na tabela efetuando os replaces necessários (o uso da expressão terá de ser dinâmica ou você poderá usar IFs fixos com as funções de acordo com a tabela, veja o que achar melhor.

Espero ter ajudado!
Abraços!
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

O OP postou o tópico em outro fórum, e teve algumas respostas lá, embora nunca tenha retornado se foram úteis ou não... :roll:

Como não foi postada versão do Oracle nem mais detalhes, postei uma solução com model e regexp_count / regexp_replace.
Meus 2 cents na época:

Selecionar tudo

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as FSITJA
 
SQL> with tab as (
  2  select 'joao *pereira* dos *santos*' nome from dual union
  3  select 'jose *silva* reis' nome from dual union
  4  select 'jose *silva* reis *farias' nome from dual union
  5  select '*fatima* oliveira' nome from dual union
  6  select '*teresinha* freitas *almeida*' nome from dual union
  7  select 'antonio maria *neves*' from dual)
  8  -- fim dos dados de exemplo, início do SQL
  9  --
 10  select n as nome, n2 as novo_nome
 11  from (select nome,
 12               row_number() over (order by 1) id,
 13               max(regexp_count(nome, '(([^*]+)|(\*[^*]*\*))')) over () max_cnt
 14          from tab)
 15  model dimension by (id as i)
 16  measures (cast(null as varchar2(4000)) as n2, cast(null as number) x, nome as n, max_cnt as mc, nome as p)
 17  rules update iterate (100) until iteration_number >= mc[1] - 1
 18  (
 19    x[any] = iteration_number,
 20    p[any] = regexp_substr(n[cv(i)], '(([^*]+)|(\*[^*]*\*))', 1, iteration_number + 1),
 21   n2[any] = n2[cv(i)] || case when regexp_like(p[cv(i)], '^\*.*\*$')
 22                               then upper(rtrim(ltrim(p[cv(i)], '*'), '*'))
 23                               else p[cv(i)] end
 24  );
 
NOME                          NOVO_NOME
----------------------------- --------------------------------------------------------------------------------
*fatima* oliveira             FATIMA oliveira
*teresinha* freitas *almeida* TERESINHA freitas ALMEIDA
antonio maria *neves*         antonio maria NEVES
joao *pereira* dos *santos*   joao PEREIRA dos SANTOS
jose *silva* reis             jose SILVA reis
jose *silva* reis *farias     jose SILVA reis farias
 
6 rows selected
 
SQL> 
Para ver as contribuições dos demais colegas, é só dar uma olhada no link abaixo:
http://www.profissionaloracle.com.br/mo ... pic&t=4295
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Como você mencionou, o símbolo poderia ser parametrizado por tabela e concatenado na expressão regular, sem problemas. Mas, é mais esforço que não sei se seria útil no momento dispensar.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Umm, caiu uma ficha agora pensando a respeito. Acho que usando XQuery daria para simplificar bastante a vida aí. A título de curiosidade vou dar uma olhada depois em casa nisso.

http://download.oracle.com/docs/cd/E118 ... xquery.htm
Avatar do usuário
Bogos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 20
Registrado em: Ter, 06 Jul 2010 8:58 am
Localização: Americana / SP
Contato:

O caso de usar uma tabela de relações seria para casos em que poderiam existir diversos caracteres que tivessem ações diversas.
Bastante interessante o select, uma solução inteligente mesmo.

Só por curiosidade, a XQuery é exclusiva da 11g? Ela tem relação apenas com XML, ou estou errado?
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Como XMLQuery envolve trabalho com sequências de caracteres, dá para usar para vários problemas, inclusive para fazer alguns tipos de parse como você sugeriu.

Por exemplo, vamos supor que temos a string '10,60,30,300,1000' e que precisamos somar as partes dela, entre vírgulas.

Uma forma seria usando expressões regulares, buscando por elementos entre vírgulas, ou com regexp_substr ou regexp_replace para isolá-los.

Isso envolveria iteração (loop), o que infelizmente é meio complicado de fazer em SQL, pois envolve ou queries hierárquicas (com Connect By) ou cláusula model. Ou para quem tem 11g a nova cláusula With recursiva.

De qualquer forma, são sintaxes e códigos um tanto complexos.

Dá para fazer a mesma coisa com XQuery e XMLTable, com um código bem limpo. Por exemplo:

Selecionar tudo

SQL> WITH t AS
  2   (SELECT '10,60,30,300,1000' str FROM dual)
  3  -- select xmltype('<e><e>' || REPLACE(str, ',', '</e><e>') || '</e></e>') from t
  4  -- fim dos dados de exemplo
  5  SELECT sum(extractvalue(column_value, 'e')) sum_val
  6    FROM t, xmltable('/e' passing xmltype('<e><e>' || REPLACE(str, ',', '</e><e>') || '</e></e>').extract('e/e'));
 
   SUM_VAL
----------
      1400
Em duas linhas se resolve o problema.

A ideia que pensei foi substituir os asteriscos (*) com tags xml, semelhante ao que você sugeriu, e parseá-las colocando o interior com upper.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Eu acho que já existiam a partir do 10g. Antes, no 9i, tem algumas funções como XMLSequence, que já foram deprecadas por não serem tão eficientes e simples quanto as novas.
Avatar do usuário
Bogos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 20
Registrado em: Ter, 06 Jul 2010 8:58 am
Localização: Americana / SP
Contato:

Bastante interessante, e até que é simples também.
Vou ler mais sobre, quem sabe até não da para melhorar scripts que já desenvolvi. :D
Responder
  • Informação