以下脚本告诉您哪个表是数据库中的特殊值。我想找到找到的表的列

时间:2019-05-13 08:12:18

标签: plsql

以下脚本可让您在数据库中查找自定义值。

我可以找出这个特殊值在哪张桌子上。 但是我不知道表格在哪一列中。 如何找到找到的表的列名。

declare
v_match_count integer;
v_counter integer;
v_owner varchar2(255) := 'HASTANE';

v_data_type varchar2(255) := 'NUMBER';

v_search_string varchar2(4000) := 1455671;


v_sql clob := '';
begin
for cur_tables in (select owner, table_name from all_tables where owner = v_owner and table_name in 
(select table_name from all_tab_columns where owner = all_tables.owner and data_type like '%' || upper(v_data_type) || '%')
order by table_name) loop
v_counter := 0;
v_sql := '';


for cur_columns in (select column_name from all_tab_columns where 
owner = v_owner and table_name = cur_tables.table_name and data_type like '%' || upper(v_data_type) || '%') loop
if v_counter > 0 then
v_sql := v_sql || ' or ';
end if;
v_sql := v_sql || 'upper(' || cur_columns.column_name || ') like ''%' || upper(v_search_string) || '%''';
v_counter := v_counter + 1;
end loop;

v_sql := 'select count(*) from ' || cur_tables.table_name || ' where ' || v_sql;

execute immediate v_sql
into v_match_count;



if v_match_count > 0 then
dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
end if;
end loop;



exception
when others then
dbms_output.put_line('Error when executing the following: ' || dbms_lob.substr(v_sql, 32600));
end;

/

1 个答案:

答案 0 :(得分:0)

这似乎不像您在生产环境中运行的那种代码,因此我认为性能不是您的主要考虑因素。既然如此,为什么不对每个列名执行单独的查询,而不将它们全部加载到具有大量OR的单个查询中呢?也许像您在下面看到的那样。我将您的匿名块移动到存储过程中,以使其更易于重用。

CREATE OR REPLACE PROCEDURE find_cols_with_values (owner_in      IN VARCHAR2,
                                                   datatype_in   IN VARCHAR2,
                                                   value_in      IN VARCHAR2)
IS
   v_match_count   INTEGER;
   v_sql           CLOB := '';
BEGIN
   FOR cur_tables
      IN (  SELECT owner, table_name
              FROM all_tables
             WHERE     owner = owner_in
                   AND table_name IN (SELECT table_name
                                        FROM all_tab_columns
                                       WHERE     owner = all_tables.owner
                                             AND data_type LIKE
                                                       '%'
                                                    || UPPER (datatype_in)
                                                    || '%')
          ORDER BY table_name)
   LOOP
      FOR cur_columns
         IN (SELECT column_name
               FROM all_tab_columns
              WHERE     owner = owner_in
                    AND table_name = cur_tables.table_name
                    AND data_type LIKE '%' || UPPER (datatype_in) || '%')
      LOOP
         v_sql :=
               'select count(*) from '
            || cur_tables.table_name
            || ' where upper('
            || cur_columns.column_name
            || ') like ''%'
            || UPPER (value_in)
            || '%''';

         EXECUTE IMMEDIATE v_sql INTO v_match_count;

         IF v_match_count > 0
         THEN
            DBMS_OUTPUT.put_line (
                  'Match in '
               || cur_tables.owner
               || ': '
               || cur_tables.table_name
               || '.'
               || cur_columns.column_name
               || ' - '
               || v_match_count
               || ' records');
         END IF;
      END LOOP;
   END LOOP;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (
            'Error when executing the following: '
         || DBMS_LOB.SUBSTR (v_sql, 32600));
END;
/

CREATE TABLE t1 (mynum NUMBER)
/

CREATE TABLE t2 (yournum VARCHAR2 (100))
/

BEGIN
   INSERT INTO t1
        VALUES (123);

   INSERT INTO t1
        VALUES (456);

   INSERT INTO t2
        VALUES ('123');

   COMMIT;
END;
/

BEGIN
   find_cols_with_values (owner_in      => USER,
                          datatype_in   => 'NUM',
                          value_in      => '123');
END;
/