2011-06-17 16 views
14

Tüm tablo ve sütunlarda bir dize için oracle veritabanımızda arama yapmam gerekiyor. , Sen ALL_TAB_COLUMNS sorgulamak gerekir İnternet'te bulduğum aşağıda sorgu var ama yürütme zaman Herhangi bir yardım En azındanOracle Tüm tabloları dize için tüm sütunlarda ara

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

Neden veritabanı dosyalarını bir grep kullanarak bulmuyorsunuz? En azından dosya/blok ofsetleri alabilir ve söz konusu tabloları bulabilirsiniz. –

cevap

30

takdir

aşağıdaki hatayı olsun 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; 
/

Bir dize arıyorsanız, neredeyse bir dizeyi saklayabilecek sütunları aramaya kendinizi sınırlamak istersiniz. Örneğin, bir dize için DATE sütununu aramak mantıklı olmaz. Ve bir BLOB sütununun içerdiği ve BLOB sütununun ikili biçimlendirmesini ayrıştırma yeteneği hakkında çok fazla ön bilgi sahibi olmadıkça, bir dizge için bir BLOB sütunu aramak mantıklı olmaz. göz önüne alındığında, ben size tam tablodaki her dize sütun için bir kez her tablo tarama ediyorum slow-- şey daha Tabii

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

gibi bu delicesine olacak istiyorum şüpheli. Orta derecede büyük tablolar ve ılımlı bir dizi dize sütunu ile, oldukça uzun bir süre alacaktır.

+0

Bu, sorgunun içinden biraz ORA-00942 hatasını verir: tablo veya görünüm mevcut değil ORA-06512: satır 12'de Bu hatayı nasıl devam ettirebilir veya yoksayılabilir – Jim

+0

@Jim - İkinci çözümüme bir istisna işleyici ekledim. Şemaunuzun dışındaki tablolara erişiminiz olması durumunda şema sahibi niteleyicisini de ekledim. –

+0

v_search_string ve match_count bildirmek zorunda kaldım ve bu işi almak için örtülü imleçte SELECT içindeki alan alanını ekleyin. Bu gerçek gem +1. – Blanthor

İlgili konular