sábado, 3 de maio de 2008

SQL - Operador "LIKE" & ESCAPE

Para a utilização do operador “LIKE”, ANSI SQL, usa-se os caracteres coringas ‘_’, ou ‘%’. Veja o exemplo abaixo:

select
*
from (
select
column_value col
from
table(ts.split_varchar2('Jan,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like 'J_n'

Acima, vimos o exemplo do coringa posicional. Ou seja, para posição que o underscore ocupar na substring de busca, no filtro, o compilador irá interpretar que qualquer caractere serve. O nosso filtro busca qualquer string de três caracteres cujo a primeira posição é ocupada pelo “J” e a última pelo “n”, a posição do meio é o coringa, portanto, qualquer caractere serve. Por isso obtivemos como resultado: “Jan” e “Jun”. Vejamos outro exemplo usando o “%”:


select
*
from (
select column_value col
from
table(ts.split_varchar2('Jan,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like 'J%'



Recapitulando, o underscore é um coringa posicional. Veja que, se por exemplo, na cláusula “where” o valor para o filtro for modificado para “like '_a_'” o resultado do select vai ser: Jan, Mar, Mai. Retornará todos os meses que possuírem a letra “a” como segundo caractere. Conforme exemplificado abaixo:


select
*
from (
select column_value col
from table(ts.split_varchar2('Jan,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like '_a_'


O Problema que muitos desenvolvedores eventualmente enfrentam é quando o caractere coringa é justamente o que ele quer usar como filtro. Por exemplo:

select
*
from (
select column_value col
from table(ts.split_varchar2('Jan,Jan_2008,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like '%_%'


Se você tentar encontrar o registro pela presença do caractere “underscore” o resultado do select não será o esperado. Conforme ilustrado abaixo:



Uma solução, é usar a palavra reservada “ESCAPE”. Desta forma você indica ao compilador SQL qual caractere coringa você deseja que ele considere para busca. Exemplo:

select
*
from (
select column_value col
from
table(ts.split_varchar2('Jan,Jan_2008,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like '%@_%' ESCAPE '@'

Para usar corretamente o ESCAPE, você precisa primeiro marcar o coringa com outro caractere o operando do “like”, exemplo: “like '%@_%'”. Em seguida, o operador do ESCAPE identifica o caractere que marcou o coringa. Exemplo: “ESCAPE '@'”.
Agora o resultado do filtro aplicado retornará o que desejamos:


Outro exemplo:


select
*
from (
select column_value col
from table(ts.split_varchar2('Jan,Jan_2008,Fev_%,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like '%@_2008' ESCAPE '@'




Se trocarmos o marcador, de “@” para “/” visando tornar nosso exemplo mais claro. Além disso, vamos testar usar como filtro a presença do caractere “%”. Para isso inclui o elemento “Fev%Wanddjah” no conjunto a ser selecionado.


select
*
from (
select column_value col
from table(ts.split_varchar2('Jan,Jan_2008, Fev,Fev%Wanddjah,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE col like '%/%Wanddjah' ESCAPE '/'


Veja o resultado:




Outra opção para solução seria usar expressões regulares:

select
*
from (
select column_value col
from table(ts.split_varchar2('Jan,Jan_2008, Jan\Fev ,Fev,Fev%Wanddjah,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE REGEXP_LIKE(col,'\')

O ESCAPE do expressões regulares é o “\” .O exemplo acima retorna todos os registros. Para escapar o especial do caractere “\” caso você precise do seu valor literal use o próprio, conforme exemplificado abaixo:
select
*
from (
select column_value col
from table(ts.split_varchar2('Jan,Jan_2008, Jan\Fev ,Fev,Fev%Wanddjah,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez', ','))
) q
WHERE REGEXP_LIKE(col,'\\').


Agora obteremos como retorno apenas: “Jan\Fev”.

O mesmo vale para os demais metacaracteres. Exemplo: “\.”, “\[”, “\]”, “\?”, “\+”, “\{” , “\}”, “\^”, e “\$”.

2 comentários:

  1. Fala Gersinho! Adicionei seu blog no meu! Adiciona o meu no seu! E, se puder, indica o meu aí! Abração e saudades, amigão!

    ResponderExcluir
  2. Me esqueci de dizer qual é o meu blog!

    http://atelier-das-ideias.blogspot.com/

    abração!

    ResponderExcluir