Som ett minimum måste du fråga ALL_TAB_COLUMNS, inte 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;
/
Om du letar efter en sträng, däremot, skulle du nästan säkert vilja begränsa dig till att leta efter kolumner som kan lagra en sträng. Det skulle till exempel inte vara meningsfullt att söka efter en sträng i en DATE-kolumn. Och om du inte har en hel del a priori kunskap om vad en BLOB-kolumn innehåller och förmågan att analysera BLOB-kolumns binära formatering, skulle det inte vara meningsfullt att söka i en BLOB-kolumn efter en sträng. Med tanke på det misstänker jag att du vill ha något mer liknande
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;
/
Naturligtvis kommer det här att gå vansinnigt långsamt - du skulle skanna varje tabell en gång för varje strängkolumn i tabellen. Med måttligt stora tabeller och ett måttligt antal strängkolumner kommer det sannolikt att ta ganska lång tid.