Vì vậy, bạn muốn thực hiện tìm kiếm văn bản miễn phí giống như Google trên cơ sở dữ liệu của mình. Điều này có thể được thực hiện nhưng hiệu suất sẽ là Teh Suck! Google nhanh chóng vì nó có các chỉ mục trên các chỉ mục của mình, các kho lưu trữ dữ liệu trùng lặp và thường tối ưu hóa mọi thứ cho chính xác loại tìm kiếm này.
Dù sao, đây là một bằng chứng về khái niệm sử dụng SQL động và từ điển dữ liệu Oracle. Lưu ý rằng tôi hạn chế các cột ở loại dữ liệu tôi muốn tìm kiếm, tức là chuỗi.
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>
Việc triển khai mạnh mẽ hơn có thể cần phải xử lý chữ hoa, chữ thường, v.v. Nếu bạn ở trên 10g trở lên thì biểu thức chính quy có thể hữu ích, nhưng việc kết hợp regex và SQL động là một điều thú vị khách hàng tiềm năng.
Tôi nhắc lại rằng màn trình diễn sẽ là Teh Suck! trên một tập dữ liệu lớn. Hầu như không thể điều chỉnh, bởi vì chúng tôi không thể lập chỉ mục mọi cột, và chắc chắn không hỗ trợ LIKE hoặc các kết quả tương tự mờ. Một cách tiếp cận thay thế sẽ là sử dụng XQuery để tạo ra một biểu diễn XML cho dữ liệu của bạn và sau đó sử dụng Văn bản để lập chỉ mục dữ liệu đó. Việc duy trì một kho lưu trữ như vậy sẽ rất tốn kém, nhưng nỗ lực sẽ là một khoản đầu tư đúng đắn nếu bạn cần chức năng này thường xuyên, đặc biệt là trong môi trường sản xuất.
Chúng tôi có thể thực hiện tìm kiếm rộng hơn trên tất cả các bảng mà chúng tôi có đặc quyền bằng cách sử dụng all_tab_cols
thay vì.
for r in ( select owner, table_name, column_name from all_tab_cols
where data_type in ('VARCHAR2', 'CHAR', 'CLOB') )
Rõ ràng là chúng ta cần đặt trước lược đồ sở hữu trong câu lệnh đã tạo.
execute immediate 'select null from '||r.owner||'.'||r.table_name
||' where '||r.column_name||' like ''%