Oracle
 sql >> база данни >  >> RDS >> Oracle

SQL изберете за всички записи, които могат да съдържат специфична стойност

И така, искате да направите подобно на Google търсене на безплатен текст във вашата база данни. Това може да се направи, но изпълнението ще бъде Teh Suck! Google е бърз, защото има индекси на своите индекси, дублирани хранилища за данни и като цяло оптимизира всичко за точно този вид търсене.

Както и да е, ето доказателство за концепцията, използвайки динамичен SQL и речника на данните на Oracle. Имайте предвид, че ограничавам колоните до типа данни, които искам да търся, т.е. низове.

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>

Може да се наложи по-стабилна реализация да обработва малки и големи букви, цели думи и т.н. Ако сте на 10g или по-висока, тогава регулярните изрази могат да бъдат полезни, но комбинирането на регулярен израз и динамичен SQL е, ъъъ, интересно перспектива.

Повтарям, че изпълнението ще бъде Teh Suck! върху голям набор от данни. На практика е невъзможно да се настрои, защото не можем да индексираме всяка колона и със сигурност не поддържаме LIKE или подобни размити съвпадения. Алтернативен подход би бил да използвате XQuery за генериране на XML представяне на вашите данни и след това да използвате Text, за да ги индексирате. Поддържането на такова хранилище би било излишно, но усилието би било разумна инвестиция, ако се нуждаете от тази функционалност редовно, особено в производствена среда.

Можем да извършим по-широко търсене във всички таблици, за които имаме привилегии, като използваме all_tab_cols вместо.

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

Очевидно трябва да поставим префикс на притежаващата схема в генерирания оператор.

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 db в приложението .Net

  2. Трябва ли процедурите и/или функциите на пакета DBMS_STANDARD да се използват в PL/SQL код?

  3. Преобразуване на интервала в минути

  4. Как мога да предам параметър на t-sql скрипт?

  5. Защо не можете да използвате OR или IN с операция OUTER JOIN?