तो, आप अपने डेटाबेस पर Google जैसी निःशुल्क टेक्स्ट खोज करना चाहते हैं। यह किया जा सकता है लेकिन प्रदर्शन तह चूसना होगा! 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 का संयोजन एक, एर, दिलचस्प है संभावना।
मैं दोहराता हूं कि प्रदर्शन तह चूक होने वाला है! एक बड़े डेटा सेट पर। ट्यून करना लगभग असंभव है, क्योंकि हम हर कॉलम को इंडेक्स नहीं कर सकते हैं, और निश्चित रूप से LIKE या इसी तरह के फ़ज़ी मैचों का समर्थन नहीं करते हैं। एक वैकल्पिक तरीका यह होगा कि आप अपने डेटा का XML प्रतिनिधित्व उत्पन्न करने के लिए XQuery का उपयोग करें और फिर इसे अनुक्रमित करने के लिए टेक्स्ट का उपयोग करें। इस तरह के भंडार को बनाए रखना ओवरहेड होगा, लेकिन प्रयास एक अच्छा निवेश होगा यदि आपको नियमित आधार की इस कार्यक्षमता की आवश्यकता है, खासकर उत्पादन वातावरण में।
हम 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 ''%