Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle Rechercher toutes les tables toutes les colonnes pour la chaîne

Au minimum, vous devez interroger ALL_TAB_COLUMNS, pas 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;
/

Si vous recherchez une chaîne, cependant, vous voudriez presque certainement vous limiter à la recherche de colonnes pouvant stocker une chaîne. Cela n'aurait aucun sens, par exemple, de rechercher une colonne DATE pour une chaîne. Et à moins que vous n'ayez une grande connaissance a priori du contenu d'une colonne BLOB et de la capacité d'analyser le formatage binaire de la colonne BLOB, cela n'aurait aucun sens de rechercher une chaîne dans une colonne BLOB. Compte tenu de cela, je suppose que vous voulez quelque chose de plus comme

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

Bien sûr, cela va être incroyablement lent - vous effectuerez une analyse complète de chaque table une fois pour chaque colonne de chaîne de la table. Avec des tables modérément volumineuses et un nombre modéré de colonnes de chaînes, cela risque de prendre un certain temps.