2017-02-15 55 views
1

我正在嘗試更新使用福利的員工的工資。每當更新時發生任何錯誤,我需要保存哪些員工ID錯誤發生。 但它給下面的錯誤在編譯時錯誤 (14,24):PLS-00201:標識符「INDX」必須聲明爲從所有保存例外中獲取失敗的標識

下面是我的代碼

PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE) 
IS 
    lv_error_string VARCHAR2(4000); 
BEGIN 
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS 
    EXECUTE IMMEDIATE 'UPDATE EMPLOYEES SET SALARY=SALARY+10000 WHERE EMP_ID=:1' 
    USING V_EMP_ID(INDX); 
EXCEPTION 
    WHEN OTHERS 
    THEN 
    FOR J IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
    LOOP 
     lv_error_string:=lv_error_string 
        ||sqlerrm (-sql%bulk_exceptions(j).error_code) 
        || ' for'||V_EMP_ID(INDX); 
    END LOOP; 
END; 

回答

2

使用此:錯誤是,在exception block您正試圖訪問正在使用的循環變量begin block

所以你|| ' for'||V_EMP_ID(INDX);應該|| ' for'||V_EMP_ID(J);

CREATE OR REPLACE PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE) 
IS 
    lv_error_string VARCHAR2(4000); 
BEGIN 
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS 
    EXECUTE IMMEDIATE 'UPDATE EMPLOYEES SET SALARY=SALARY+10000 WHERE EMP_ID=:1' 
    USING V_EMP_ID(INDX); 
EXCEPTION 
    WHEN OTHERS 
    THEN 
    FOR J IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
    LOOP 
     lv_error_string:=lv_error_string 
        ||sqlerrm (-sql%bulk_exceptions(j).error_code) 
        || ' for'||V_EMP_ID(J); 
    END LOOP; 
END; 

不知道爲什麼你使用Execute Immediate時,你可以輕鬆做到如下:

CREATE OR REPLACE PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE) 
IS 
    lv_error_string VARCHAR2(4000); 
BEGIN 
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS 
    UPDATE EMPLOYEES 
    SET SALARY=SALARY+10000 
    WHERE EMP_ID= V_EMP_ID(INDX); 

EXCEPTION 
    WHEN OTHERS 
    THEN 
    FOR J IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
    LOOP 
     lv_error_string:=lv_error_string 
        ||sqlerrm (-sql%bulk_exceptions(j).error_code) 
        || ' for'||V_EMP_ID(J); 
    END LOOP; 
END; 
+0

這工作,但並沒有給我的員工ID爲發生錯誤@邢 – PTK

+0

所以來你的問題,我不知道爲什麼你在做一個'立即執行'當你可以直接運行'update'時。看到我更新的帖子。你沒有得到任何'employee_id' coz oracle doenot找到任何'異常'。 – XING

0

我建議去與一個DML語句。是的DML錯誤洛金斯是possible.Hope這有助於

--Creating a error log table 
BEGIN 
    DBMS_ERRLOG.create_error_log (dml_table_name => 'EMPLOYEES'); 
END; 
/
--ERR$_EMPLOYEES --> Errro table created 


--Insertion with erroreous record 
UPDATE EMPLOYEES 
SET SALARY   = SALARY + 10000 
where EMP_ID    in (<EMP_ID COLLECTION array 
OR simple EMP_IDs>) LOG ERRORS 
INTO ERR$_EMPLOYEES ('UPDATE') REJECT LIMIT UNLIMITED; 

--Error will be logged into ERR$_EMPLOYEES table 
+1

LOG ERRORS是一個好主意,但請記住,它將保留在單個語句中成功修改的行,這與SAVE EXCEPTIONS(語句級錯誤抑制)非常不同。 –

+0

是的。我在這裏只考慮了行級錯誤處理 –