问题
I have a procedure that takes an input of 2 Associative arrays and after some basic count checks, does a FORALL statement to insert the data into a table.
Here is the procedure:
PROCEDURE INSERT_RECS(P_PROD_TYP IN prod_type, P_PROD_ADD_PK IN prod_pk_type)
IS
uniq_key EXCEPTION;
PRAGMA EXCEPTION_INIT(uniq_key, -00001);
loc_cnt NUMBER;
BEGIN
IF P_PROD_TYP.COUNT = P_PROD_ADD_PK.COUNT THEN
FORALL i IN P_PROD_TYP.FIRST .. P_PROD_TYP.LAST
INSERT INTO product_table ( pk,
id,
created_by,
created_on,
last_chg_by,
last_chg_on)
VALUES (P_PROD_ADD_PK(i),
P_PROD_TYP(i).id,
P_PROD_TYP(i).created_by,
P_PROD_TYP(i).created_on,
NULL,
NULL);
END IF;
EXCEPTION
WHEN uniq_key THEN
loc_cnt := SQL%BULK_EXCEPTIONS.count;
FOR i IN 1 .. loc_cnt LOOP
dbms_output.put_line('EXCEPTION: Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE) ||
' SQLERRM: ' || SQLERRM ||
' SQLCODE: ' || SQLCODE ||
' stack: ' || SYS.dbms_utility.format_call_stack);
END LOOP;
RETURN;
END;
What I would like is if I hit an exception, is there a way that I could have view of the record that is causing the issue, essentially the index in the associative array or at least have the SQL% info have the info.
I have look at the following: http://www.dba-oracle.com/plsql/t_plsql_exceptions.htm
but this outputs the info about the column but that is not what I am after.
回答1:
Not sure if really answers your query but you can use the loop variable i in exception block to display the content of the exception array in your case. See below an example procedure:
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
---trying to rasie an exception by using a calculation
SET SALARY=SALARY * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
WHERE ID_E= V_EMP_ID(INDX);
EXCEPTION
WHEN OTHERS
THEN
FOR i IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
LOOP
---Am printing the value of the exception array.
dbms_output.put_line('exception Raised for record' ||V_EMP_ID(i));
END LOOP;
END;
/
Ouput:
SQL> DECLARE
empid DBMS_SQL.NUMBER_TABLE;
BEGIN
empid (1) := 1;
empid (2) := 9;
PROC1 (empid);
END;
/
exception Raised for record 1
PL/SQL procedure successfully completed.
来源:https://stackoverflow.com/questions/43879447/trying-to-get-the-actual-data-that-cause-an-exception