2

次のように、いくつかのデータ更新を実行したいと思います。

    CREATE OR REPLACE PROCEDURE PROC_MDM_RUN_DATA_MAPPING
     IS
        sqlString VARCHAR2(2000) := '';
        CURSOR csr_updates 
        IS
            SELECT  trim(table_name) AS table_name, 
                    trim(column_name) AS column_name, 
                    trim(old_value) AS old_value, 
                    trim(new_value) AS new_value 
            FROM C_MDM_MAPPING_TABLE 
            WHERE area = 'MDM' and rownum < 10
            AND run_update = 'Y' ;

    BEGIN
          FOR rec IN csr_updates 
          LOOP
             BEGIN
                sqlString := 'UPDATE ' || rec.table_name || 
                      ' SET ' || rec.column_name || ' = ''' || rec.new_value || '''
                      WHERE TRIM(' || rec.column_name || ') = ''' || rec.old_value || ''';'  ; 

                INSERT INTO C_MDM_ERROR_LOG  ( msg ) VALUES ( sqlString ); 

                dbms_output.put_line(sqlString) ; -- works, giving correct SQL
                execute immediate sqlString ;  -- fails

             END;
          END LOOP;
          COMMIT;

    END PROC_MDM_RUN_DATA_MAPPING;
    /

このプロシージャは、データの更新ごとに正しいSQLをコンパイルして生成します-以下の例:

    UPDATE S_CFM_UNIVERSITY_ALL SET MASTER_UNI_NAME = 'Chung-Ang University'
                      WHERE TRIM(MASTER_UNI_NAME) = 'Chung Ang University';

しかし、executeimmediateステートメントはエラー「PLS-00103:次のいずれかを予期しているときにシンボル「end-of-file」に遭遇しました:」を返します。

; 象徴 ";" 続行するには、「ファイルの終わり」の代わりに使用しました。」

末尾のセミコロンを除外しようとしましたが、エラーが返されます

  ORA-00933: SQL command not properly ended

助けてくれてありがとう。

4

2 に答える 2

1

次のように、改行を埋め込まずに SQL を生成してみてください。

CREATE OR REPLACE PROCEDURE PROC_MDM_RUN_DATA_MAPPING IS
  sqlString VARCHAR2(2000) := '';

  CURSOR csr_updates IS
    SELECT  trim(table_name) AS table_name, 
            trim(column_name) AS column_name, 
            trim(old_value) AS old_value, 
            trim(new_value) AS new_value 
      FROM C_MDM_MAPPING_TABLE 
      WHERE area = 'MDM' AND
            rownum < 10 AND
            run_update = 'Y';
  BEGIN
    FOR rec IN csr_updates LOOP
      sqlString := 'UPDATE ' || rec.table_name || 
                   ' SET ' || rec.column_name || ' = ''' || rec.new_value ||
                   ''' WHERE TRIM(' || rec.column_name || ') = ''' ||
                   rec.old_value || '''';

      INSERT INTO C_MDM_ERROR_LOG  ( msg ) VALUES ( sqlString ); 

      dbms_output.put_line(sqlString) ; -- works, giving correct SQL
      execute immediate sqlString ;
    END LOOP;

    COMMIT;
  END PROC_MDM_RUN_DATA_MAPPING;

生成された SQL のセミコロンは必要ないと思うので削除し、ループ内の BEGIN...END ペアも必要ありません。

これが役立つことを願っています。共有してお楽しみください。

于 2013-03-22T03:08:04.160 に答える
0

すべての助けに感謝します - 末尾のセミコロンが必要ないという点で上記の答えは正しいですが、フォローアップとして - データに一重引用符である2番目の問題がありました.

次のようにカーソルを変更すると、その問題が修正されました

    SELECT  trim(table_name) AS table_name, 
            trim(column_name) AS column_name, 
            REPLACE(trim(old_value),'''','''''') AS old_value, 
            REPLACE(trim(new_value),'''','''''') AS new_value 
    FROM C_MDM_MAPPING_TABLE 

テーブルと列の名前は問題ないことがわかっています (システムから取得されます) が、「入力を信頼しない」に戻ります。

ありがとう

于 2013-03-22T03:22:57.910 に答える