2013-07-11 76 views
2

我需要找到在我的Oracle數據庫中包含一些值的表。在數據庫的所有表中搜索值

我發現了兩個查詢。第一個查詢我想:

declare 
    l_pattern varchar2(100) := 'По какому вопросу звонили?'; 
    cursor cf is select table_name,column_name from user_tab_columns where data_type = 'VARCHAR2' order by table_name; 

    t_str varchar2(2000) := 'select count(*) from dual where exists(select null from '; 
    l_str varchar2(2000); 
    l_where_clause varchar2(2000) := ' where 1=0'; 
    l_last_table varchar2(100) := ''; 
    l_cnt number := 0; 

    procedure query_ (i_txt varchar2) is 
    l_txt varchar2(4000) := i_txt; 
    l_ln number := length(l_txt); 
    l_pieces number := ceil(l_ln/250); 
    begin 
    for i in 1..l_pieces loop 
     dbms_output.put_line(substr(i_txt, 1+250*(i-1),least(250,l_ln-250*(i-1)))); 
    end loop; 
    dbms_output.new_line; 
    end; 

begin 
    for i in cf loop 
    if l_last_table <> i.table_name then 
    -- dbms_output.put_line(l_str||l_where_clause); 
     execute immediate l_str || l_where_clause ||')' into l_cnt; 
     if l_cnt > 0 then 
     query_ ('select * from ' || l_last_table || l_where_clause || ';'); 
     end if; 
     l_cnt := 0; 
     l_where_clause := ' where 1=0'; 
    end if; 
    l_last_table := i.table_name; 
    l_str := t_str || i.table_name; 
    l_where_clause := l_where_clause || ' OR ' || i.column_name || ' like ''' ||l_pattern||''''; 
    end loop; 
    execute immediate l_str || l_where_clause ||')' into l_cnt; 
    if l_cnt > 0 then 
    query_ ('select * from ' || l_last_table || l_where_clause || ';'); 
    end if; 
end; 

這將返回錯誤:

Error starting at line 1 in command: 
declare 
... 
end; 

Error report: ORA-06502: PL/SQL: numeric or value error: character 
string buffer too small ORA-06512: at line 35 
06502. 00000 - "PL/SQL: numeric or value error%s" 
*Cause:  
*Action: 

select * from MV_CATALOG_ITEM where 1=0 OR CODE like 'По какому 
вопросу звонили?' OR UUID like 'По какому вопросу звонили?' OR 
TITLE like 'По какому вопросу звонили?' OR PARENTITEMUUID like 'По 
какому вопросу звонили?' OR CATALOGTITLE like 'По какому вопросу 
звонили?' OR FOLDERTITLE like 'По какому вопросу звонили?' OR 
CATALOGUUID like 'По какому вопросу звонили?' OR CATALOGCODE like 'По 
какому вопросу звонили?' OR FOLDERUUID like 'По какому вопросу 
звонили?'; 

select * from MV_HIERARCHICAL_TEMPLATES where 1=0 OR STRINGCONTENT2 
like 'По какому вопросу звонили?' OR STRINGCONTENT3 like 'По какому 
вопросу звонили?' OR IDENTIFIER like 'По какому вопросу звонили?' OR 
TEMPLATEUUID like 'По какому вопросу звонили? ' OR ATTRIBUTETITLE like 
'По какому вопросу звонили?' OR STRINGCONTENT like 'По какому вопросу 
звонили?' OR GROUPTITLE like 'По какому вопросу звонили?' OR INSTUUID 
like 'По какому вопросу звонили?' OR OBJUUID like 'По какому вопросу 
звонили?' OR TYP ECODE like 'По какому вопросу звонили?' OR GROUPUUID 
like 'По какому вопросу звонили?'; 

我想第二個查詢:

select table_name, 
     column_name 
    from(select table_name, 
       column_name, 
       to_number(
       extractvalue(
        xmltype(
        dbms_xmlgen.getxml(
         'select count(*) c from ' || table_name || 
         ' where to_char(' || column_name || ') = ''JONES''' 
        ) 
        ), 
        'ROWSET/ROW/C' 
       ) 
       ) cnt 
      from (select utc.*, rownum 
        from user_tab_columns utc 
       where data_type in ('CHAR', 'VARCHAR2'))) 
where cnt >= 0 

這一個返回表和列和錯誤的大名單:

Error starting at line 1 in command: 
select table_name, 
... 
where cnt >= 0 

Error report: 
SQL Error: ORA-19202: Error occurred in XML processing 
ORA-00936: missing expression 
ORA-06512: at "SYS.DBMS_XMLGEN", line 176 
ORA-06512: at line 1 
19202. 00000 - "Error occurred in XML processing%s" 
*Cause: An error occurred when processing the XML function 
*Action: Check the given error message and fix the appropriate problem 

我找不到我自己的方式。

+0

的[全部搜索字段中的所有表的特定值(甲骨文)可能重複(http://stackoverflow.com/questions/208493/search-all-字段在所有表中爲特定值-oracle) –

+0

我總是得到「匿名塊complited」!爲什麼?? –

+0

這不是件好事,它意味着它有效嗎?或者你的意思是你沒有看到與你的字符串匹配的預期表/列?您需要'設置serveroutput'來查看dbms_output消息(在SQL * Plus或SQL Developer中,或者可能是其他客戶端)。如果這仍然沒有顯示,那麼也許沒有匹配。 –

回答

3

謝謝大家!以前的腳本實施非常緩慢。 我得到了我這個劇本值:

DECLARE 
    match_count integer; 
    v_search_string varchar2(4000) := 'advcgtfs000080000ict1mosqiomujrk'; 

BEGIN 
    FOR t IN (SELECT owner, 
        table_name, 
        column_name 
       FROM all_tab_columns 
      WHERE data_type in ('VARCHAR2')) 
    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; 
/
1

您之前作爲答案發布的代碼(並且由於某種原因沒有移到問題中)幾乎會作爲一個相當簡單的版本進行操作;與大多是未成年人在這裏複製的,但一個重要的,變化:

SET SERVEROUTPUT ON SIZE 100000 

DECLARE match_count INTEGER; 
    v_owner all_tab_cols.owner%type := 'NAUCRM'; 
    v_data_type all_tab_cols.data_type%type :='VARCHAR2'; 
    v_search_string VARCHAR2(4000) := 'PC_Number'; 
BEGIN 
    FOR t IN (SELECT table_name, column_name 
     FROM all_tab_cols 
     WHERE owner = v_owner and data_type = v_data_type) 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; 
/

關鍵的變化,因爲我在評論中已經提到的,是車主必須是大寫(除非你的用戶是建真奇怪!) ,所以'NAUCRM'而不是'naucrm'

相關問題