2011-06-17 6 views
14

oracleデータベースですべてのテーブルとカラムの文字列を検索する必要があります。 、あなたは、ALL_TAB_COLUMNSを照会する必要があり、私は私がオンラインで見つける以下のクエリを持っていますが、私はそれを実行したとき、私は任意のヘルプは、最低でもOracleすべてのテーブルのすべてのカラムを検索する

ORA-06550: line 6, column 31: 
PL/SQL: ORA-00904: "COLUMN_NAME": invalid identifier 
ORA-06550: line 6, column 12: 
PL/SQL: SQL Statement ignored 
ORA-06550: line 8, column 30: 
PLS-00364: loop index variable 'T' use is invalid 
ORA-06550: line 7, column 4: 
PL/SQL: Statement ignored 
ORA-06550: line 12, column 38: 
PLS-00364: loop index variable 'T' use is invalid 
ORA-06550: line 12, column 16: 
PL/SQL: Statement ignored 

BEGIN 
    FOR t IN (SELECT table_name, column_name FROM all_tables) LOOP 
    EXECUTE IMMEDIATE  
    'SELECT COUNT(*) FROM '||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.table_name ||' '||t.column_name||' '||match_count); 
      END IF; 
    END LOOP; 
END; 
/
+1

grepを使用してデータベースファイルを検索してみませんか?少なくとも、ファイル/ブロックのオフセットを取得し、問題のテーブルを見つけることができます。 –

答えて

30

を高く評価している

次のエラーを取得していない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; 
/

しかし、文字列を探している場合は、文字列を格納できる列を探すことをほぼ確実に制限したいでしょう。たとえば、DATE列で文字列を検索することは意味がありません。 BLOB列に含まれる内容とBLOB列のバイナリ形式を解析する能力についての先験的な知識が豊富でない限り、BLOB列で文字列を検索することは意味がありません。私はあなたがよりもちろん

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; 
/

ような何かをしたい疑い、ということを考えると、これはめちゃくちゃあなたが完全なテーブル内のすべての文字列に対して一度すべてのテーブルをスキャンしたいslow--になるだろう。適度に大きなテーブルと中程度の数の文字列を使用すると、かなりの時間がかかる可能性があります。

+0

ORA-00942の次のエラーが表示されます。テーブルまたはビューが存在しません。 ORA-06512:12行目 このエラーを再開または無視するにはどうすればいいですか? – Jim

+0

@Jim - 2番目の解決策に例外ハンドラを追加しました。また、スキーマの外部の表にアクセスできる場合に備えて、スキーマ所有者修飾子を追加しました。 –

+0

私はv_search_stringとmatch_countを宣言し、暗黙のカーソルでSELECTにownerフィールドを追加してこの作業を行う必要がありました。これは本当の宝石+1です。 – Blanthor