2013-03-22 123 views
2

我想要做一些數據的更新來更新內容如下:執行立即通過for循環

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'; 

但立即執行的語句給出了錯誤 「出現符號PLS-00103’:

; 符號「;」代替「文件結束」繼續。「

我試圖排除尾隨分號,但返回錯誤

ORA-00933: SQL command not properly ended 

任何幫助表示讚賞,感謝。

+2

與執行立即使用時,您不需要的SqlString分號,你確定你的光標查詢所有列的返回值?可能有一個空值的行並導致sql命令沒有正確結束錯誤 – 2013-03-22 03:00:07

+1

是的,rs是對的。刪除動態SQL字符串中的';',你會沒事的。 – Rachcha 2013-03-22 03:04:53

+0

感謝rs - 所有列都返回值,但一些值包含單引號,我需要檢查 – acutesoftware 2013-03-22 03:06:49

回答

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對內部這也是不需要的循環。

我希望這會有所幫助。分享並享受。

0

感謝您提供的所有幫助 - 上面的答案是正確的,因爲不需要尾隨分號,但作爲後續操作 - 第二個問題是數據中的單引號。

改變光標固定如下這個問題

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 

表和列名被稱爲是OK(他們來自系統),但它會回到「永遠不要相信輸入」。

感謝