Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Wybór SQL dla wszystkich rekordów, które mogą posiadać określoną wartość

Tak więc chcesz przeprowadzić bezpłatne wyszukiwanie tekstu w swojej bazie danych w stylu Google. Można to zrobić, ale występ będzie Teh Suck! Google jest szybki, ponieważ ma indeksy w swoich indeksach, zduplikowane magazyny danych i ogólnie optymalizuje wszystko pod kątem dokładnie tego rodzaju wyszukiwania.

W każdym razie, oto dowód koncepcji przy użyciu dynamicznego SQL i słownika danych Oracle. Zwróć uwagę, że ograniczam kolumny do typu danych, które chcę wyszukać, tj. Ciągów.

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>

Bardziej niezawodna implementacja może wymagać obsługi wielkości liter, całych słów itp. Jeśli korzystasz z wersji 10g lub wyższej, wyrażenia regularne mogą być przydatne, ale połączenie wyrażeń regularnych i dynamicznego SQL jest… hmmm, interesujące perspektywa.

Powtarzam, że występ będzie Teh Suck! na dużym zbiorze danych. Dostrojenie jest praktycznie niemożliwe, ponieważ nie możemy zindeksować każdej kolumny, a już na pewno nie obsługujemy podobnych rozmytych dopasowań. Alternatywnym podejściem byłoby użycie XQuery do wygenerowania reprezentacji danych XML, a następnie użycie tekstu do ich indeksowania. Utrzymanie takiego repozytorium byłoby kosztownością, ale wysiłek byłby rozsądną inwestycją, jeśli potrzebujesz tej funkcji regularnie, szczególnie w środowisku produkcyjnym.

Możemy przeprowadzić szersze wyszukiwanie we wszystkich tabelach, do których mamy uprawnienia, używając all_tab_cols zamiast.

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

Oczywiście musimy poprzedzić schemat właściciela w wygenerowanej instrukcji.

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle SQL — oznaczanie rekordów na podstawie daty rekordu w porównaniu z historią

  2. Oracle hierarchiczna klauzula startowa kwerendy od join

  3. SQL - Uzyskaj dodatkowe rekordy oprócz rekordów przefiltrowanych w warunku gdzie

  4. Jak usunąć przyczynę wystąpienia wyjątku Hibernate IllegalArgumentException podczas wywoływania setter?

  5. Oracle wstawia znak do łańcucha