【问题标题】:OracleSQLDeveloper Loop through all columns in all tables to find and document the table and field name [duplicate]Oracle SQL Developer循环遍历所有表中的所有列以查找并记录表和字段名称[重复]
【发布时间】:2020-01-11 16:47:11
【问题描述】:

我的公司迁移到了一个新的数据库(从 SQL Server 到 Oracle),但没有向我提供太多关于新数据库以及它如何与旧数据库映射的文档。我需要在新数据库中找到特定值,并能够确定它们在哪个表/列中找到。我正在寻找一个查询或存储过程来循环遍历在每一列和每一行中查找特定值的表。找到该值后,我需要记录表的名称和找到该值的字段。我不确定这是否可以通过查询或存储过程最好地完成,或者是否有其他方法可以完成这。

-查理

【问题讨论】:

  • 我们在谈论多少数据? # 表 #column #rows?这可能会推动这种方法。它可能不是最快的方法,但请看一下动态 sql 的 DBMS_SQL 包。您可以通过编程方式获取列名/值。

标签: sql oracle oracle-sqldeveloper


【解决方案1】:

这是一种选择;看看它是否有帮助。读取代码中的 cmets。

由于我在本示例中使用 SQL*Plus,因此我启用了输出:

SQL> set serveroutput on;

示例一:

SQL> -- Looking for a string: SCOTT
SQL>
SQL> declare
  2    l_str   varchar2(500);   -- SELECT statement to be used as dynamic SQL
  3    l_value varchar2(20);    -- value you are looking for
  4    l_cnt   number;          -- number of rows that contain L_VALUE value
  5  begin
  6    -- I'm looking for a string SCOTT in current schema
  7    l_value := 'SCOTT';
  8
  9    -- Loop through all tables; I'm restricting the list to only two tables.
 10    -- You'd probably want to remove the WHERE clause
 11    for cur_t in (select table_name
 12                  from user_tables
 13                  where table_name in ('EMP', 'DEPT')
 14                 ) loop
 15      -- Loop through all columns in every table from CUR_T
 16      for cur_c in (select column_name
 17                    from user_tab_columns
 18                    where table_name = cur_t.table_name
 19                      -- Adjust data type, according to L_VALUE value because if
 20                      -- you're looking for a string, you can't just compare it to
 21                      -- e.g. DATE datatype; you'll get the "invalid number" error
 22                      and data_type like '%CHAR%'
 23                   ) loop
 24        -- Compose a SELECT statement. It might differ, depending on value you're
 25        -- looking for. Strings have to be enclosed into single quotes (CHR(39))
 26        l_str := 'select count(*) from ' || cur_t.table_name ||
 27                 ' where '|| cur_c.column_name || ' = ' ||
 28                 chr(39) || l_value || chr(39);
 29
 30        -- To make sure it is correctly written, display it first using
 31        -- dbms_output.put_line(l_str);
 32
 33        -- Run the SELECT statement
 34        execute immediate l_str into l_cnt;
 35
 36        if l_cnt > 0 then
 37           -- SCOTT was found in some table; display it
 38           dbms_output.put_line(cur_t.table_name ||'.'|| cur_c.column_name ||
 39                                ' contains ' || l_cnt || ' values I am looking for');
 40        end if;
 41      end loop;
 42    end loop;
 43  end;
 44  /
EMP.ENAME contains 1 values I am looking for

PL/SQL procedure successfully completed.

SQL>

示例二:我修改的行是#3、7、22和28(搜索数字而不是字符串):

SQL> -- Looking for number "10"
SQL>
SQL> declare
  2    l_str   varchar2(500);   -- SELECT statement to be used as dynamic SQL
  3    l_value number;          -- value you are looking for
  4    l_cnt   number;          -- number of rows that contain L_VALUE value
  5  begin
  6    -- I'm looking for a number 10 in current schema
  7    l_value := 10;
  8
  9    -- Loop through all tables; I'm restricting the list to only two tables.
 10    -- You'd probably want to remove the WHERE clause
 11    for cur_t in (select table_name
 12                  from user_tables
 13                  where table_name in ('EMP', 'DEPT')
 14                 ) loop
 15      -- Loop through all columns in every table from CUR_T
 16      for cur_c in (select column_name
 17                    from user_tab_columns
 18                    where table_name = cur_t.table_name
 19                      -- Adjust data type, according to L_VALUE value because if
 20                      -- you're looking for a string, you can't just compare it to
 21                      -- e.g. DATE datatype; you'll get the "invalid number" error
 22                      and data_type = 'NUMBER'
 23                   ) loop
 24        -- Compose a SELECT statement. It might differ, depending on value you're
 25        -- looking for. Strings have to be enclosed into single quotes (CHR(39))
 26        l_str := 'select count(*) from ' || cur_t.table_name ||
 27                 ' where '|| cur_c.column_name || ' = ' ||
 28                 l_value;
 29
 30        -- To make sure it is correctly written, display it first using
 31        -- dbms_output.put_line(l_str);
 32
 33        -- Run the SELECT statement
 34        execute immediate l_str into l_cnt;
 35
 36        if l_cnt > 0 then
 37           -- "10" was found in some table; display it
 38           dbms_output.put_line(cur_t.table_name ||'.'|| cur_c.column_name ||
 39                                ' contains ' || l_cnt || ' values I am looking for');
 40        end if;
 41      end loop;
 42    end loop;
 43  end;
 44  /
DEPT.DEPTNO contains 1 values I am looking for
EMP.DEPTNO contains 3 values I am looking for

PL/SQL procedure successfully completed.

SQL>

【讨论】:

    【解决方案2】:

    您可以查询 DBA_TABLES 和 DBA_TAB_COLUMNS 以获取所有模式表。

    【讨论】:

      猜你喜欢
      • 2013-02-04
      • 2017-09-08
      • 2017-03-09
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-29
      • 1970-01-01
      相关资源
      最近更新 更多