Expressões Regulares em Banco de Dados, muito além do Like – Parte 02

 

III – Busca de Expressões Regulares no SGBD Oracle

O Oracle versão 10G , ou superior,  possui as seguintes funções de busca baseada no uso de expressões regulares: REGEXP_LIKE(),REGEXP_REPLACE(),REGEXP_SUBSTR() e REGEXP_COUNT(), essa última novidade da versão 11G.

REGEXP_LIKE(x, padrão[,opção_correspondente])  -  Realiza a busca  em x da expressão regular definida no parâmetro padrão. Opção_correspondente  pode ser definida com os seguintes valores:

 

  • ‘c’  - Especifica correspondência com diferenciação de maiúsculas e minúsculas( Padrão – case-Sensitive)
  • ‘i’   - Especifica a busca sem diferenciação de caracteres maiúsculos e minúsculos(case-Insensitive)
  • ‘n’  - Que permite usar o operador de correspondência com qualquer caractere.
  • ‘m’ - Que trata x como uma linha múltipla.
  • ‘x’  - ignora espaços em branco.


A semelhança com o comando LIKE não é mera coincidência, mas o leitor já poderá notar a maior flexibilidade no uso de REGEXP_LIKE  em relação ao operador  LIKE.

Considerando que a melhor maneira de aprender é com a utilização prática, estarei ilustrando a utilização com vários pequenos exemplos  de uso, que poderão ser estudados e adaptados a outras necessidades.

Nesse primeiro exemplo suponhamos a necessidade de achar em uma tabela de clientes todos os clientes com data de nascimento entre  1970 e 1975. Podemos realizar a busca, usando expressões regulares, da seguinte forma:

SELECT  nome, sobrenome, data_nascimento

FROM clientes

WHERE REGEXP_LIKE(TO_CHAR(data_nascimento, 'YYYY'), '^197[0-5]$');

Devemos ter em mente que ERs, ao contrário do operador LIKE, tem a tendência de nos trazer tudo, sem a necessidade dos coringas (%), dessa forma precisamos estar atentos para restringir a informação de retorno ao desejado. 

Para quem não tem ainda experiência com expressões regulares, podemos definir, como exemplo,  um conjunto numérico de muitas formas, de forma que [0123456789] é igual à [0-9], esses detalhes podem tornar seu código muito mais legível e elegante, e economizar digitação é claro. No exemplo anterior poderíamos  ler a expressão da seguinte forma, retorne todos os clientes (nome, sobrenome, data de nascimento), cujo ano  de nascimento se inicie com 197(“^197”) e termine (“$” ) com um elemento de 0 até 5 (“[0-5]$”).
    

Outro exemplo de recuperação de registros dos clientes, podemos ter a necessidade de recuperar em uma base qualquer os clientes cujo sobrenome se iniciem com ‘C’ ou ‘c’, realmente um exemplo simples. Nesse caso  podemos lançar mão, por exemplo, do seguinte código, onde observem o metacaracter “^” garante a busca no inicio do campo e a opção correspondente “i”  uma busca case-insensitive:

SELECT  nome, sobrenome, data_nascimento

FROM clientes

WHERE REGEXP_LIKE(sobrenome, '^C’, ‘i’);

Para recuperar os registros dos clientes que se chamem Flávio ou Flavio, podemos usar o seguinte o código:

 

SELECT  nome, sobrenome, data_nascimento

FROM clientes

WHERE REGEXP_LIKE(nome , '^FL[aá]’, ‘i’);

Note nesse caso que os elementos da lista “a ou “á” não possuem separadores e que a busca é case-insentive.

Nesse ponto muitos podem colocar que esse mesmo tipo de busca pode ser feita por meio de LIKE em SQL ou por meio de buscas textuais. Nesse instante devemos pensar que para cada caso existe uma solução mais adequada, e que para nesses exemplos a solução mais simples elegante é realmente lançar mão das ERs, mas deixo bem claro que existirão situações que a utilização de soluções textuais, fonéticas, ou até mesma a combinação de várias dessas técnicas combinadas ainda com Ers, poderão se mostrar úteis ou até mesmo necessárias.

Continuando com nossos exemplos, podemo
s trazer uma seleção de linhas em que o nome possua exatamente cinco letras:

SELECT  nome

FROM clientes

WHERE REGEXP_LIKE(nome , '^.....$','i');

Podemos observar que o número de caracteres desejadas também poderia ser expresso da seguinte maneira, no bloco
WHERE da nossa expressão:

REGEXP_LIKE(nome, '^.{5}$','i');

Nesse momento vamos supor que queremos procurar dois nomes ao mesmo tempo, ou ‘joão’ ou ‘maria’:

 

SELECT  nome

FROM clientes

WHERE REGEXP_LIKE(nome , '(joão|maria)','i');

Estes exemplos simples tiveram como objetivo, demonstrar tanto a versatilidade quanto a simplicidade das ERS, e como sua utilização pode se expandir para expnadir para muito além do nosso conhecido comando LIKE.

Não poderíamos deixar de citar que podemos lançar mão de ERs nos SGBDs para outras funções que não somente a busca, podemos utiliza-los, por exemplo para restringir entradas nos SGBDs. Para tanto podemos utilizar também as ERs para construção de constraints, por exemplo, para definir o formato que o números de telefones devem ser armazenados no SGBD, por exemplo (xxx) xxx-xxxxx, poderíamos lançar mão do seguinte comando:

  
ALTER TABLE cliente

   ADD (CONSTRAINT formato_numero_telefone
   CHECK (REGEXP_LIKE(numero_telefone,
 '^\([[:digit:]]{3}\) [[:digit:]]{3}-[[:digit:]]{4}$')));

Além de REGEXP_LIKE o Oracle disponibiliza as seguintes funções com suporte a expressões
regulares:

REGEXP_REPLACE() – O uso dessa função é para procurar um padrão e substituí-lo por um
string dada

REGEXP_SUBSTR() – Retorna parte de uma string com recursos avançados. estende as
funcionalidades da função SUBSTR, deixando você pesquisar uma string para uma expressão
regular padrão. Esta função é útil se você precisar o conteúdo de uma string, mas não
corresponder a sua posição na string original. A função retorna a string como VARCHAR2 ou
CLOB.


REGEXP_COUNT() –Novidade do Oracle 11G - , Usado para obter a quantidade de vezes que
uma expressão regular ocorre em uma string.

As expressões regulares possuem várias vantagens sobre os tradicionais comandos SQLs (LIKE, INSTR, SUBSTR e REPLACE) desses apenas o operador LIKE possui facilidades de busca ( % e _ ), e mesmo assim não suporta mecanismos de busca de padrões ou expressões complexas, sendo muito difícil reproduzir expressões regulares complexas com comandos SQL

IV – E quanto a índices?

Todos sabemos que os índices são um fator muito importante na busca de informações em função da melhor desempenho que podem proporcionar as buscas. Assim como com a utilização em SGBDs do comando LIKE , os índices padrões criados em um determinado campo não são utilizados nas buscas por ERs, no entanto, isso é muito importante, você pode criar índices baseados em função para implementar desempenho em suas consultas com ERs, caso contrário suas consultas com ERs farão uma varredura completa na tabela(full table scan) o que poderá causar contenção no banco de dados.

V – Para saber mais

KLEENE, STEPHEN COLE ,?MATHEMATICAL LOGIC, DOVER SCIENCE 2002 1.Ed

 

Links

 

http:/www.aurelio.net 

 

http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions129.htm

 

http://pt.wikipedia.org/wiki/Express%C3%A3o_regular

 

http://pt.wikipedia.org/wiki/POSIX

 

http://www.oracle.com/technology/software/products/sql/index.html

 

First Expressions, Jonathan Gennick,  http://www.oracle.com/technology/oramag/oracle/03-sep/o53sql.html