0

Oracle DB を使用しています。クエリを実行する Toad があります。

私は2つの列を持っています

  • タイプCD
  • 説明

スキーマでProduct_BIS

Product_BISこれらの列 Typecd と説明を持つスキーマ内のすべてのテーブルを取得するストアド プロシージャがあることを知りたいです。もしそうなら、 Typecd ='11' and description='Nokia' が存在するかどうかを確認したいと思います。

これを見つける方法は?これをチェックするための単純なストアドプロシージャはありますか?

注:スキーマ Product_BIS には約 300 のテーブルがあります。そのため、手動で確認することは困難です

4

2 に答える 2

2

必要なのは、データ ディクショナリに問い合わせて、特定の列を持つすべてのテーブルを検索し、クエリを生成して、それらの列に特定の値を持つ行を持つテーブルを見つけるものです。これを行うための Oracle 組み込みはありません。

これを行う通常のアプローチは、動的 SQL です。あなたは、データベースにオブジェクトを作成する権限がないと言いました。それでは、匿名ブロックを実行してください。

このコードは、SQL*Plus またはその他の IDE で実行できます。SERVEROUTPUT が有効になっていることを確認してください。

rownum = 1アセンブルされたステートメントでの使用に注意してください。これにより、複数のレコードが条件に一致する場合にブロックが TOO_MANY_ROWS 例外をスローするのを防ぎます。投稿された質問では、プログラムが 1 つ以上の行の存在をアサートする必要があるだけなので、これは許容されます。実際の要件が異なる場合は、明らかにコードを修正する必要があります。たとえば、一致したレコードの数を表示する必要がある場合は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 回限りの要件であり、問​​題ではないと思います。ただし、スキーマ、列名、および値のさまざまな順列に対して繰り返し実行するスクリプトの場合は、置換変数を使用するスクリプトとしてこれを書き直す必要があります。

于 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 に答える