И така, искате да направите подобно на 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 ''%