Ở mức tối thiểu, bạn cần truy vấn ALL_TAB_COLUMNS, không phải ALL_TABLES
DECLARE
match_count integer;
v_search_string varchar2(4000) := <<string you want to search for>>;
BEGIN
FOR t IN (SELECT owner, table_name, column_name FROM all_tab_columns) LOOP
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM '||t.owner || '.' || t.table_name||
' WHERE '||t.column_name||' = :1'
INTO match_count
USING v_search_string;
IF match_count > 0 THEN
dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
END IF;
END LOOP;
END;
/
Tuy nhiên, nếu bạn đang tìm kiếm một chuỗi, gần như chắc chắn bạn sẽ muốn hạn chế mình tìm kiếm các cột có thể lưu trữ một chuỗi. Chẳng hạn, sẽ không hợp lý khi tìm kiếm một chuỗi DATE trong cột DATE. Và trừ khi bạn có nhiều kiến thức tiên nghiệm về những gì cột BLOB chứa và khả năng phân tích cú pháp định dạng nhị phân của cột BLOB, thì việc tìm kiếm một chuỗi trong cột BLOB sẽ không có ý nghĩa gì. Vì vậy, tôi nghi ngờ bạn muốn một cái gì đó giống hơn
DECLARE
match_count integer;
v_search_string varchar2(4000) := <<string you want to search for>>;
BEGIN
FOR t IN (SELECT owner,
table_name,
column_name
FROM all_tab_columns
WHERE data_type in ('CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2',
'CLOB', 'NCLOB') )
LOOP
BEGIN
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM '||t.owner || '.' || t.table_name||
' WHERE '||t.column_name||' = :1'
INTO match_count
USING v_search_string;
IF match_count > 0 THEN
dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
END IF;
EXCEPTION
WHEN others THEN
dbms_output.put_line( 'Error encountered trying to read ' ||
t.column_name || ' from ' ||
t.owner || '.' || t.table_name );
END;
END LOOP;
END;
/
Tất nhiên, điều này sẽ cực kỳ chậm - bạn sẽ quét toàn bộ mỗi bảng một lần cho mỗi cột chuỗi trong bảng. Với các bảng lớn vừa phải và số lượng cột chuỗi vừa phải, điều đó có thể mất khá nhiều thời gian.