0

我正在使用 Oracle 数据库。我有 Toad 来执行我的查询。

我有两列

  • 打字机
  • 描述

在架构中Product_BIS

我想知道是否有任何存储过程来检索架构Product_BIS中具有这些列 Typecd 和描述的所有表。如果是这样,我想检查 Typecd ='11'and description='Nokia' 是否存在。

如何找到这个?是否有任何简单的存储过程来检查这个。任何人都可以帮助我

注意:Schema Product_BIS 中有大约 300 个表。所以手动检查很困难

4

2 回答 2

2

您想要的是询问数据字典以查找具有某些列的所有表,然后生成查询以查找这些表中的哪些具有在这些列中具有特定值的行。没有内置的 Oracle 可以执行此操作。

执行此操作的常规方法是动态 SQL。您说您没有在数据库中创建对象的权限。好吧,好吧,只需运行一个匿名块。

此代码可以在 SQL*Plus 或任何其他 IDE 中运行。只需确保您已启用 SERVEROUTPUT。

注意rownum = 1汇编语句中的使用。如果多个记录与条件匹配,这可以防止块抛出 TOO_MANY_ROWS 异常。这是可以接受的,因为发布的问题只需要程序断言存在一行或多行。如果实际要求不同,那么显然您需要修改代码。例如,如果您需要显示匹配记录的数量,则选择count(*)一个数字变量并相应地更改 DBMS_OUTPUT 语句。

declare
    v char(1);
begin
    for r in ( select table_name from all_tab_columns
                where owner = 'PRODUCT_BIS'
                and column_name = 'TYPECD'
                intersect
                select table_name from all_tab_columns
                where owner = 'PRODUCT_BIS'
                and column_name = 'DESCRIPTION' )
    loop
        begin
            execute immediate
                 'select null from '||r.table_name
                   ||' where typecd=''11'' and description = ''nokia'' and rownum = 1'
                 into v;
            dbms_output.put_line ( 'those values exist in '||r.table_name);
       exception
            when no_data_found then
                 dbms_output.put_line ( 'no occurrence of those values in '||r.table_name);
       end;
    end loop;
end;

此解决方案使用硬编码值。我认为这是一次性要求,所以没关系。但是,如果是一个脚本,您将希望针对模式、列名和值的许多不同排列重复运行,那么您应该将其重新编写为使用替换变量的脚本。

于 2012-06-26T10:14:43.967 回答
0

可能这会帮助您在特定模式中找到特定值

CREATE OR REPLACE FUNCTION FIND_IN_SCHEMA (VAL VARCHAR2)
   RETURN VARCHAR2
IS
   V_OLD_TABLE   USER_TAB_COLUMNS.TABLE_NAME%TYPE;
   V_WHERE       VARCHAR2 (4000);
   V_FIRST_COL   BOOLEAN                            := TRUE;

   TYPE RC IS REF CURSOR;

   C             RC;
   V_ROWID       VARCHAR2 (20);
BEGIN
   FOR R IN (SELECT   T.*
                 FROM USER_TAB_COLS T, USER_ALL_TABLES A
                WHERE T.TABLE_NAME = A.TABLE_NAME
                  AND T.DATA_TYPE LIKE '%CHAR%'
             ORDER BY T.TABLE_NAME)
   LOOP
      IF V_OLD_TABLE IS NULL
      THEN
         V_OLD_TABLE := R.TABLE_NAME;
      END IF;

      IF V_OLD_TABLE <> R.TABLE_NAME
      THEN
         V_FIRST_COL := TRUE;

         -- DBMS_OUTPUT.PUT_LINE('searching ' || V_OLD_TABLE);
         OPEN C
          FOR 'select rowid from "' || v_old_table || '" ' || V_WHERE;

         FETCH C
          INTO V_ROWID;

         LOOP
            EXIT WHEN C%NOTFOUND;
            DBMS_OUTPUT.PUT_LINE ('  rowid: ' || V_ROWID || ' in '
                                  || V_OLD_TABLE
                                 );

            FETCH C
             INTO V_ROWID;
         END LOOP;

         V_OLD_TABLE := R.TABLE_NAME;
      END IF;

      IF V_FIRST_COL
      THEN
         V_WHERE := ' where ' || R.COLUMN_NAME || ' like ''%' || VAL || '%''';
         V_FIRST_COL := FALSE;
      ELSE
         V_WHERE :=
            V_WHERE || ' or ' || R.COLUMN_NAME || ' like ''%' || VAL || '%''';
      END IF;
   END LOOP;

   RETURN 'Success';
END;
/
于 2012-06-26T07:41:40.107 回答