sql >> Databasteknik >  >> RDS >> Oracle

SQL-val för alla poster som kan ha ett specifikt värde

Så du vill göra en Google-liknande fritextsökning över din databas. Detta kan göras men föreställningen kommer att vara Teh Suck! Google är snabb eftersom den har index på sina index, dubbletter av datalager och optimerar i allmänhet allt för just denna typ av sökning.

Hur som helst, här är ett proof of concept med hjälp av dynamisk SQL och Oracles dataordbok. Observera att jag begränsar kolumnerna till den typ av data jag vill söka efter, dvs strängar.

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>

En mer robust implementering kan behöva hantera skiftläge, hela ord, etc. Om du är på 10g eller högre kan reguljära uttryck vara användbara, men att kombinera regex och dynamisk SQL är en, eh, intressant prospekt.

Jag upprepar att föreställningen kommer att vara Teh Suck! på en stor datamängd. Det är praktiskt taget omöjligt att ställa in, eftersom vi inte kan indexera varje kolumn, och absolut inte för att stödja LIKE eller liknande luddiga matchningar. Ett alternativt tillvägagångssätt skulle vara att använda XQuery för att generera en XML-representation av dina data och sedan använda Text för att indexera den. Att underhålla ett sådant förvar skulle vara overhead, men ansträngningen skulle vara en bra investering om du behöver denna funktionalitet på regelbunden basis, särskilt i en produktionsmiljö.

Vi kan göra en bredare sökning i alla tabeller vi har behörighet för genom att använda all_tab_cols istället.

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

Uppenbarligen måste vi prefixa ägarschemat i den genererade satsen.

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


  1. Kan MySQL konvertera en lagrad UTC-tid till lokal tidszon?

  2. ORA-00955-namnet används redan av ett befintligt objekt

  3. DAY() Exempel – MySQL

  4. org.hibernate.MappingException:egenskapsmapping har fel antal kolumner i ENUM-entiteten