Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle Durchsucht alle Tabellen alle Spalten nach Zeichenfolgen

Sie müssen mindestens ALL_TAB_COLUMNS abfragen, nicht 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;
/

Wenn Sie jedoch nach einer Zeichenfolge suchen, möchten Sie sich mit ziemlicher Sicherheit darauf beschränken, nach Spalten zu suchen, die eine Zeichenfolge speichern können. Es wäre beispielsweise nicht sinnvoll, eine DATE-Spalte nach einem String zu durchsuchen. Und wenn Sie nicht viel a priori Wissen darüber haben, was eine BLOB-Spalte enthält, und die Fähigkeit haben, die binäre Formatierung der BLOB-Spalte zu analysieren, würde es keinen Sinn machen, eine BLOB-Spalte nach einer Zeichenfolge zu durchsuchen. Angesichts dessen vermute ich, dass Sie eher etwas wie

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

Natürlich wird dies wahnsinnig langsam sein - Sie würden jede Tabelle einmal für jede Zeichenfolgenspalte in der Tabelle vollständig scannen. Bei mäßig großen Tabellen und einer mäßigen Anzahl von Zeichenfolgenspalten wird das wahrscheinlich eine ganze Weile dauern.