sql >> Databasteknik >  >> RDS >> Oracle

Oracle Sök efter sträng i alla tabeller, alla kolumner

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.




  1. Alternativ till att använda LIMIT nyckelord i en underfråga i MYSQL

  2. Vad är nytt i ProxySQL 2.0

  3. PostgreSQL 9.3:Dynamisk pivottabell

  4. Knee-Jerk Wait Statistik :PAGELATCH