sql >> Base de Datos >  >> RDS >> Oracle

Selección de SQL para todos los registros que pueden contener un valor específico

Por lo tanto, desea realizar una búsqueda de texto libre similar a Google en su base de datos. Esto se puede hacer, pero la actuación será Teh Suck! Google es rápido porque tiene índices en sus índices, almacenes de datos duplicados y, en general, optimiza todo precisamente para este tipo de búsqueda.

De todos modos, aquí hay una prueba de concepto usando SQL dinámico y el diccionario de datos de Oracle. Tenga en cuenta que restrinjo las columnas al tipo de datos que quiero buscar, es decir, cadenas.

SQL> set serveroutput on size unlimited
SQL> declare
  2      dummy varchar2(1);
  3  begin
  4      for r in ( select table_name, column_name from user_tab_cols
  5                 where data_type in ('VARCHAR2', 'CHAR', 'CLOB') )
  6      loop
  7          begin
  8              execute immediate 'select null from '||r.table_name
  9                      ||' where '||r.column_name||' like ''%&search_value%'' '
 10                      ||' and rownum = 1'
 11                 into dummy;
 12              dbms_output.put_line('Found it in >>>'
 13                     ||r.table_name||'.'||r.column_name);
 14          exception
 15              when others then
 16                  -- bad practice ahoy!
 17                  null;
 18          end;
 19      end loop;
 20  end;
 21  /
Enter value for search_value: MAISIE
old   9:                ||' where '||r.column_name||' like ''%&search_value%'' '
new   9:                ||' where '||r.column_name||' like ''%MAISIE%'' '
Found it in >>>T23.NAME

PL/SQL procedure successfully completed.

SQL>

Es posible que una implementación más robusta necesite manejar mayúsculas y minúsculas, palabras completas, etc. Si tiene 10 g o más, las expresiones regulares podrían ser útiles, pero combinar expresiones regulares y SQL dinámico es, ejem, interesante. prospecto.

Repito que la actuación va a ser Teh Suck! en un gran conjunto de datos. Es virtualmente imposible de ajustar, porque no podemos indexar cada columna, y ciertamente no admitir LIKE o coincidencias parciales similares. Un enfoque alternativo sería usar XQuery para generar una representación XML de sus datos y luego usar Text para indexarlo. Mantener dicho repositorio sería una sobrecarga, pero el esfuerzo sería una buena inversión si necesita esta funcionalidad de forma regular, especialmente en un entorno de producción.

Podemos realizar una búsqueda más amplia en todas las tablas en las que tenemos privilegios usando all_tab_cols en cambio.

for r in ( select owner, table_name, column_name from all_tab_cols
                   where data_type in ('VARCHAR2', 'CHAR', 'CLOB') )

Obviamente, necesitamos prefijar el esquema propietario en la declaración generada.

execute immediate 'select null from '||r.owner||'.'||r.table_name
                       ||' where '||r.column_name||' like ''%