PL / SQL帮助检查特定模式的特定表中的特定值

时间:2012-06-26 05:50:59

标签: oracle plsql oracle10g oracle11g data-warehouse

我正在使用Oracle DB。我有Toad来执行我的查询。

我有两列

  • typecd
  • 描述
架构Product_BIS

中的

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

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

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

2 个答案:

答案 0 :(得分: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;

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

答案 1 :(得分: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;
/