3

Oracle データベースで何らかの値を含むテーブルを見つける必要があります。

2 つのクエリが見つかりました。私が試した最初のクエリ:

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 'По какому вопросу звонили?';

私が試した2番目のクエリ:

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

私は自分で方法を見つけることができません。

4

2 に答える 2

5

全てに感謝!以前のスクリプトの実装は非常に遅かった。私はこのスクリプトで自分の価値を得ました:

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;
/
于 2013-07-15T04:24:05.627 に答える
2

以前に回答として投稿したコード (何らかの理由で質問に移動していないコード) は、かなり単純なバージョンとして必要なことをほぼ実行します。ほとんどマイナーですが、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'

于 2013-07-12T10:50:49.847 に答える