segunda-feira, 2 de junho de 2014

Procurando um valor no Oracle

Uma aplicação de ERP estava gerando um erro e eu precisava encontrar o registro no banco de dados (Oracle). As tabelas têm nomes inescrutáveis, então decidi que eu tinha que pesquisar todas para encontrar o valor que enxergava no monitor.

A solução foi bastante simples; com a ajuda dos metadados, percorri todas as colunas de tipos interessantes a procura do valor.


declare
  s varchar2(4096);
begin
  for i in (select * 
            from all_tab_cols 
            where owner='XY' 
                  and data_type in ('NUMBER','VARCHAR2') 
            order by table_name) 
  loop
    begin
      execute immediate 'select '||i.column_name
                     ||' from xy.'||i.table_name
                     ||' where '||i.column_name||'=''145960''' 
              into s;
      dbms_output.put_line(i.table_name||'.'||i.column_name);
    exception when no_data_found then null;
    end;
  end loop;
end;
Isto é, determinei que no esquema XY apenas interessam as colunas NUMBER e VARCHAR2 e pesquisei coluna por coluna todas as tabelas. Por sorte, XY tem, ao todo, pouco mais que 1 milhão de registros. O valor que eu procurava era 145960, como se pode deduzir da consulta gerada para cada coluna. Se a consulta não retorna nada, o Oracle lança o erro no_data_found. Por isso, o dbms_output.put_line() só é executado quando o valor for encontrado.

Em poucos segundos, encontrei a tabela e a coluna. Devido ao sucesso fácil, não encontrei motivos para transformar a consulta numa procedure ou numa function.

Nenhum comentário: