2017-02-15 36 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

是的。我在这里只考虑了行级错误处理 –