1

我正在尝试使用 forall 更新员工的工资。每当更新时发生任何错误时,我都需要保存发生了哪个员工 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;
4

2 回答 2

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;
于 2017-02-15T07:31:34.123 回答
0

我建议使用单个 DML 语句。是的,DML 错误登录是可能的。希望这会有所帮助

--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
于 2017-02-15T09:37:04.950 回答