1

Oracle SQLを使用してスキーマ内の個人データを難読化するSQL DeveloperでSQLスクリプトを開発しています。スクリプトは、難読化する必要があるテーブルと列とその方法のリストを含む「OBFUS_TABLE」というテーブルを調べます。次に、データを変更しながらテーブルをループします。

実際のループと難読化プロセスをテストしましたが、問題なく動作します。また、OBFUS_TABLE を作成して値を挿入するループの直前まで、スクリプトの開始を正常にテストしました。ループを実行しようとすると、「テーブルまたはビューが存在しません」というエラーで失敗し、2 つを一緒に実行しようとすると問題が発生します。以下のコードのスニペット:

    alter session set current_schema = SYSTEM;

    DECLARE
      t_count                   NUMBER;
      t_count2                  NUMBER;
      p_tname                   VARCHAR2(100);
      p_cname                   VARCHAR2(100);
      l_datatype                VARCHAR2(100);
    BEGIN

      SELECT COUNT(*) INTO t_count FROM all_tables  WHERE table_name = 'OBFUS_TABLE';
      SELECT COUNT(*) INTO t_count2 FROM all_tables  WHERE table_name = 'OBFUS_LOG';

      IF (t_count = 0)
        THEN
          EXECUTE immediate 'create table OBFUS_TABLE( TABLENAME VARCHAR2(200 BYTE), COLUMNNAME VARCHAR2(200 BYTE), DATA_TYPE VARCHAR2(20 BYTE), ACTIVE  VARCHAR(1 BYTE)  )';
      END IF;

      IF (t_count2 = 0)
        THEN
          EXECUTE immediate 'CREATE TABLE OBFUS_LOG (SRC_TABLENAME VARCHAR2(50 BYTE), SRC_TABLE_ROW_COUNT NUMBER, COPY_TABLENAME VARCHAR2(50 BYTE), COPY_TABLE_ROW_COUNT NUMBER, UPDATE_DATE TIMESTAMP(6) )';
      END IF;

    EXECUTE immediate 'INSERT INTO OBFUS_TABLE VALUES (''OB_MYTABLE1'',''SRNM'',''NAME'',''Y'')';
    COMMIT;


      FOR x IN (SELECT TABLENAME, COLUMNNAME, DATA_TYPE FROM OBFUS_TABLE WHERE ACTIVE='Y')
      LOOP
        p_tname    := upper(x.TABLENAME);  -- Table name
        p_cname    := upper(x.COLUMNNAME); -- Column name
        l_datatype := upper(x.DATA_TYPE);
        dbms_output.put_line('Started: '||TO_CHAR(sysdate,'YYYY/MM/DD HH24:MI:SS'));
      END LOOP;

    END;

注: 実際には、上記のものとまったく同じ形式で約 30 の挿入ステートメントがあります。この投稿をパディングしすぎるので削除しましたが、すべての挿入ステートメントを手動でチェックしましたが、すべて正しいです。

問題は、SQL Developerが実行前にコードの「健全性チェック」を行い、ループを先読みしてOBFUS_TABLEが存在しないことに気づきますが、そのコードが実行されるまでにOBFUS_TABLEを理解できないことだと思います必ず存在します。

これを回避する方法はありますか?GOTOステートメントが役立つかもしれないと思いましたが、うまくいきませんでした。ソリューションを 2 つの個別のスクリプトではなく、1 つのスクリプトとして保持したいと思いますが、これを回避する唯一の方法がそうすることである場合は、そうすることができると思います。どんな助けでも大歓迎です。

4

1 に答える 1

5

次のように、選択に動的 SQL を使用する必要があります。

declare
    ...
    l_tname    varchar2(100);
    l_cname    varchar2(100);
    l_datatype varchar2(100);
    rc         sys_refcursor;
begin
    ...
    open rc for 'SELECT TABLENAME, COLUMNNAME, DATA_TYPE  
                 FROM OBFUS_TABLE WHERE ACTIVE=''Y''';
    loop
        fetch rc into l_tname, l_cname, l_datatype;
        exit when rc%notfound;
        dbms_output.put_line('Started: '||TO_CHAR(sysdate,'YYYY/MM/DD HH24:MI:SS'));
    end loop;
    close rc;
end;
于 2012-05-23T16:46:09.100 に答える