sql >> Database >  >> RDS >> Oracle

SQL selecteren voor alle records die een specifieke waarde kunnen bevatten

U wilt dus een Google-achtige vrije tekstzoekopdracht over uw database uitvoeren. Dit kan worden gedaan, maar de uitvoering zal Teh Suck zijn! Google is snel omdat het indexen op zijn indexen heeft, gegevensopslag dupliceert en over het algemeen alles optimaliseert voor precies dit soort zoekopdrachten.

Hoe dan ook, hier is een proof of concept met behulp van dynamische SQL en het Oracle-datawoordenboek. Merk op dat ik de kolommen beperk tot het type gegevens waarnaar ik wil zoeken, d.w.z. strings.

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>

Een robuustere implementatie moet mogelijk hoofdletters, hele woorden, enz. verwerken. Als u 10g of hoger gebruikt, kunnen reguliere expressies nuttig zijn, maar het combineren van regex en dynamische SQL is een, eh, interessant prospect.

Ik herhaal dat de voorstelling Teh Suck! op een grote dataset. Het is vrijwel onmogelijk om af te stemmen, omdat we niet elke kolom kunnen indexeren, en zeker niet om LIKE of soortgelijke fuzzy matches te ondersteunen. Een alternatieve benadering zou zijn om XQuery te gebruiken om een ​​XML-representatie van uw gegevens te genereren en vervolgens Tekst te gebruiken om deze te indexeren. Het onderhouden van zo'n repository zou overhead zijn, maar het zou een goede investering zijn als je deze functionaliteit regelmatig nodig hebt, vooral in een productieomgeving.

We kunnen een bredere zoekopdracht uitvoeren in alle tabellen waarvoor we rechten hebben door all_tab_cols te gebruiken in plaats van.

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

Het is duidelijk dat we het eigenaarsschema moeten voorvoegen in de gegenereerde instructie.

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


  1. 7 manieren om dubbele rijen te vinden terwijl u de primaire sleutel in MySQL negeert

  2. Scala en MySQL JDBC-stuurprogramma

  3. XML doorgeven als parameter aan opgeslagen procedure in Oracle

  4. Hoe kan ik de kolommen van twee tabellen samenvoegen tot één uitvoer?