FORALL ... SAVE EXCEPTIONS
Hi folks,
I want to transfer BULK data from exception_test1 to exception_test2 with FORALL ... SAVE EXCEPTIONS
procedure execute successfull but no data transfer & no exception raise..
create or replace
PROCEDURE forall_exception
AS
TYPE t_tab IS TABLE OF exception_test1%ROWTYPE;
l_tab t_tab := t_tab();
l_error_count NUMBER;
ex_dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381); --24381
-- Perform a bulk operation.
BEGIN
FORALL i IN l_tab.first .. l_tab.last SAVE EXCEPTIONS
INSERT INTO exception_test2
VALUES l_tab(i);
EXCEPTION
WHEN ex_dml_errors THEN
l_error_count := SQL%BULK_EXCEPTIONS.count;
DBMS_OUTPUT.put_line('Number of failures: ' || l_error_count);
FOR i IN 1 .. l_error_count LOOP
DBMS_OUTPUT.put_line('Error: ' || i ||
' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
-- END;
END;
Hi,
You have declared the collection. To get the data into the collection, you need to fetch the data into it and then use it later.
Modify your code to something like:
create or replace PROCEDURE forall_exception (in_key_val in number)
AS
TYPE t_tab IS TABLE OF exception_test1%ROWTYPE;
l_tab t_tab := t_tab();
l_error_count NUMBER;
ex_dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381); --24381
-- Perform a bulk operation.
BEGIN
SELECT * BULK COLLECT INTO l_tab FROM exception_test1 WHERE key_val = in_key_val;
FORALL i IN l_tab.first .. l_tab.last SAVE EXCEPTIONS
INSERT INTO exception_test2 VALUES l_tab(i);
EXCEPTION
WHEN ex_dml_errors THEN
l_error_count := SQL%BULK_EXCEPTIONS.count;
DBMS_OUTPUT.put_line('Number of failures: ' || l_error_count);
FOR i IN 1 .. l_error_count LOOP
DBMS_OUTPUT.put_line('Error: ' || i ||
' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
/With this, you will have the record fetched into collection l_tab. If any exception occurs, those exceptions will be saved and printed later.
Similar Messages
-
How to handle multiple save exceptions (Bulk Collect)
Hi
How to handle Multiple Save exceptions? Is it possible to rollback to first deletion(of child table) took place in the procedure.
There are 3 tables
txn_header_interface(Grand Parent)
orders(parent)
order_items (Child)
One transaction can have one or multiple orders in it.
and one orders can have one or multiple order_items in it.
We need to delete the data from child table first then its parent and then from the grand parent table.if some error occurs anywhere I need to rollback to child record deletion. Since there is flag in child table which tells us when to delete data from database.
Is it possible to give name to Save exceptions?
e.g.
FORALL i IN ABC.FIRST..ABC.LAST SAVE EXCEPTIONS A
FORALL i IN abc.FIRST..ABC.LAST SAVE EXCEPTIONS B
if some error occurs then
ROLLBACK A; OR ROLLBACK B;
Please find the procedure attached
How to handle the errors with Save exception and rollback upto child table deletion.
CREATE OR REPLACE
PROCEDURE DELETE_CONFIRMED_DATA IS
TYPE TXN_HDR_INFC_ID IS TABLE OF TXN_HEADER_INTERFACE.ID%TYPE;
TXN_HDR_INFC_ID_ARRAY TXN_HDR_INFC_ID;
ERROR_COUNT NUMBER;
BULK_ERRORS EXCEPTION;
PRAGMA exception_init(bulk_errors, -24381);
BEGIN
SELECT THI.ID BULK COLLECT
INTO TXN_HDR_INFC_ID_ARRAY
FROM TXN_HEADER_INTERFACE THI,ORDERS OS,ORDER_ITEMS OI
WHERE THI.ID = OS.TXN_HDR_INFC_ID
AND OS.ID = OI.ORDERS_ID
AND OI.POSTING_ITEM_ID = VPI.ID
OI.DW_STATUS_FLAG =4 --data is moved to Datawarehouse
MINUS
(SELECT THI.ID FROM TXN_HEADER_INTERFACE THI,ORDERS OS,ORDER_ITEMS OI
WHERE THI.ID = OS.TXN_HDR_INFC_ID
AND OS.ID = OI.ORDERS_ID
OI.DW_STATUS_FLAG !=4);
IF SQL%NOTFOUND
THEN
EXIT;
END IF;
FORALL i IN TXN_HDR_INFC_ID_ARRAY.FIRST..TXN_HDR_INFC_ID_ARRAY.LAST SAVE
EXCEPTIONS
DELETE FROM ORDER_ITEMS OI
WHERE OI.ID IN (SELECT OI.ID FROM ORDER_ITEMS OI,ORDERS
OS,TXN_HEADER_INTERFACE THI
WHERE OS.ID = OI.ORDERS_ID
AND OS.TXN_HDR_INFC_ID = THI.ID
AND THI.ID = TXN_HDR_INFC_ID_ARRAY(i));
FORALL i IN TXN_HDR_INFC_ID_ARRAY.FIRST..TXN_HDR_INFC_ID_ARRAY.LAST SAVE
EXCEPTIONS
DELETE FROM ORDERS OS
WHERE OS.ID IN (SELECT OS.ID FROM ORDERS OS,TXN_HEADER_INTERFACE THI
WHERE OS.TXN_HDR_INFC_ID = THI.ID
AND THI.ID = TXN_HDR_INFC_ID_ARRAY(i));
FORALL i IN TXN_HDR_INFC_ID_ARRAY.FIRST..TXN_HDR_INFC_ID_ARRAY.LAST SAVE
EXCEPTIONS
DELETE FROM TXN_HEADER_INTERFACE THI
WHERE THI.ID = TXN_HDR_INFC_ID_ARRAY(i);
COMMIT;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE, 'DD-MON-YY HH:MIPM')||':
DELETE_CONFIRMED_DATA: INFO:DELETION SUCCESSFUL');
EXCEPTION
WHEN OTHERS THEN
ERROR_COUNT := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE, 'DD-MON-YY HH:MIPM')||':
DELETE_CONFIRMED_DATA: ERROR:Number of errors is ' ||ERROR_COUNT);
FOR indx IN 1..ERROR_COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Error ' || indx || 'occurred during
'||'iteration'||SQL%BULK_EXCEPTIONS(indx).ERROR_INDEX);
DBMS_OUTPUT.PUT_LINE('Error is '
||SQLERRM(-SQL%BULK_EXCEPTIONS(indx).ERROR_CODE));
END LOOP;
END DELETE_CONFIRMED_DATA;
Any suggestion would be of great help.
Thanks in advance
AnuIf you have one or two places in your code that need multiple exceptions, just do it with multiple catch statements. Unless you are trying to write the most compact Programming 101 homework program, inventing tricks to remove two lines of code is not good use of your time.
If you have multiple catches all over your code it could be a code smell. You may have too much stuff happening inside one try statement. It becomes hard to know what method call throws one of those exceptions, and you end up handling an exception from some else piece of code than what you intended. E.g. you mention NumberFormatException -- only process one user input inside that try/catch so it is easy to see what error message is given if that particular input is gunk. The next step of processing goes inside its own try/catch.
In my case, the ArrayIndexOutOfBoundsException and
NumberFormatException should be handled by the same way.Why?
I don't think I have ever seen an ArrayIndexOutOfBoundsException that didn't indicate a bug in the code. Instead of an AIOOBE perhaps there should be an if statement somewhere that prevents it, or the algorithm logic should prevent it automatically. -
I'm trying to use the SAVE EXCEPTION clause and load all the records that error into an error table. example of my code is below. This code does not compile, it does not like the way I refrence a column in the collection ie.
recs.sku(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX)
is there a better way to do this?
this is the code:
TYPE table_object IS TABLE OF tran_data_stage%ROWTYPE;
recs TABLE_OBJECT;
l_errors NUMBER(9);
CURSOR c_tdh_source IS
SELECT
sku,
store,
wh,
vdate,
NULL
FROM tran_data_history
WHERE vdate between sysdate -6
and sysdate;
BEGIN
OPEN c_tdh_source;
LOOP
BEGIN
FETCH c_tdh_source BULK COLLECT INTO recs LIMIT 100;
FORALL i IN recs.FIRST..recs.LAST SAVE EXCEPTIONS
INSERT INTO tran_data_stage VALUES recs(i);
EXIT WHEN c_tdh_source%NOTFOUND;
EXCEPTION
WHEN OTHERS THEN
l_errors := SQL%BULK_EXCEPTIONS.COUNT;
dbms_output.put_line('Number of errors is ' || l_errors);
FOR i IN 1..l_errors LOOP
dbms_output.put_line('Error ' || i || ' occurred during '||
'iteration ' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
dbms_output.put_line('Oracle error is ' ||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
INSERT INTO tran_data_stage_errors VALUES
recs.sku(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX), --here is the error
5,
sysdate
END LOOP;
END;
END LOOP;
COMMIT;
CLOSE c_tdh_source;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('others error occured' || SQLERRM);
END;Shouldn't that berecs(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX).sku
-
SAVE EXCEPTIONS when fetching from cursors by BULK COLLECT possible?
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
Hello,
I'm using an Cursor's FETCH by BULK COLLECT INTO mydata...
Is it possible to SAVE EXCEPTIONS like with FORALL? Or is there any other possibility to handle exceptions during bulk-fetches?
Regards,
MartinThe cursor's SELECT-statement uses TO_DATE(juldat,'J')-function (for converting an julian date value to DATE), but some rows contain an invalid juldat-value (leading to ORA-01854).
I want to handle this "rows' exceptions" like in FORALL.
But it could also be any other (non-Oracle/self-made) function within "any" BULK instruction raising (un)wanted exceptions... how can I handle these ones?
Martin -
I'm currently using a bulk collect (limit = 100) and a forall insert to load roughly 6.2 million records into a table. If I leave the "Save Exceptions" clause out of the procedure, all 6.2 million records are loaded without an error. THe amount of memory used never exceeds 40MB. If I include the "Save Exceptions" clause and put in the code to record any errors encountered, the memory jumps to over 200MB and the procedure is exceedingly slow. Also, I put a debugging statement after each forall insert to validate that the SQL%BULK_EXCEPTIONS.COUNT = 0 for each iteration. The procedure still completes with no errors, but the memory utilized is still way too high.
Has anyone run into this before? Is there an environmental setting that needs to be set to use "Save Exceptions" with many rows of data?
We are currently running 9.2.0.3.0.
Thanks,
ScottHello.
Thank you for your answers. Let me react:
re 1. - this is the last possible solution which I don't want to take unless it is clear that the upgrade will fix the problem
re 2. APPEND - just trying to improve the insert, I am not sure if this bit works, however it does not affect the memory problem
re 3. in accordance with my understanding the LIMIT clause will not help. The amount of data we process in one step is not huge - not more then 10 000 records.
re 4. we are already doing it, I was just interested whether someone has already seen this problem or not.
So far I have not found any solutions... -
Hello Gurus,
I have a problem with the Save Exceptions. I am using database 11g.
When I am doing bulk insert I would like to insert the error records into a new table. But when I am inserting
the error records I am getting the error "error:- ORA-00984: column not allowed here
ORA-24381: error(s) in array DML".
I am putting my code below.
DECLARE
CURSOR C_FRT2STORE IS
SELECT ROWID,
STORE_CD,
MNR_CD,
'FRT',
DT,
TO_DATE('31-DEC-2049'),
FRT_FAC,
TRUNC(SYSDATE),
'ADMINUSR'
FROM FRT2STORE;
CURSOR C_FRT2STORE_EXC_TAB IS
SELECT 'Y'
FROM ALL_TABLES
WHERE TABLE_NAME = 'FRT2STORE_EXC';
TYPE STORE$MNR2CST_REC_TYPE IS RECORD
(C_STORE$MNR2CST_ROWID VARCHAR2(100),
C_STORE_CD STORE$MNR2CST.STORE_CD%TYPE,
C_MNR_CD STORE$MNR2CST.MNR_CD%TYPE,
C_CST_CD STORE$MNR2CST.CST_CD%TYPE,
C_BEG_DT STORE$MNR2CST.BEG_DT%TYPE,
C_END_DT STORE$MNR2CST.END_DT%TYPE,
C_FAC NUMBER(13,3), --STORE$MNR2CST.FAC%TYPE,
C_AMT STORE$MNR2CST.AMT%TYPE,
C_CUBIC_AMT STORE$MNR2CST.CUBIC_AMT%TYPE,
C_LST_ACTN_DT STORE$MNR2CST.LST_ACTN_DT%TYPE,
C_EMP_CD STORE$MNR2CST.EMP_CD%TYPE
TYPE STORE$MNR2CST_TYPE IS TABLE OF STORE$MNR2CST_REC_TYPE
INDEX BY PLS_INTEGER;
STORE$MNR2CST_COL STORE$MNR2CST_TYPE;
V_TOT_REC PLS_INTEGER := 0;
V_FRT2STORE_EXC_TAB CHAR(1);
V_TOT_REC_IN_STORE$MNR2CST PLS_INTEGER;
V_ERR_REC PLS_INTEGER;
BULK_ERRORS EXCEPTION;
PRAGMA EXCEPTION_INIT (BULK_ERRORS, -24381);
BEGIN
--GETTING DATA FROM FRT2STORE TABLE AND INSERTING INTO THE STORE$MNR2CST TABLE
SELECT COUNT(1)
INTO V_TOT_REC_IN_STORE$MNR2CST
FROM STORE$MNR2CST ;
IF V_TOT_REC_IN_STORE$MNR2CST = 0 THEN
OPEN C_FRT2STORE;
LOOP
FETCH C_FRT2STORE BULK COLLECT INTO STORE$MNR2CST_COL LIMIT 1000;
EXIT WHEN STORE$MNR2CST_COL.COUNT = 0;
V_TOT_REC := STORE$MNR2CST_COL.COUNT;
IF V_TOT_REC > 0 THEN
BEGIN
FORALL I IN STORE$MNR2CST_COL.FIRST..STORE$MNR2CST_COL.LAST SAVE EXCEPTIONS
INSERT INTO STORE$MNR2CST
(STORE_CD,
MNR_CD,
CST_CD,
BEG_DT,
END_DT,
FAC,
AMT,
CUBIC_AMT,
LST_ACTN_DT,
EMP_CD
VALUES
(STORE$MNR2CST_COL(I).C_STORE_CD,
STORE$MNR2CST_COL(I).C_MNR_CD,
STORE$MNR2CST_COL(I).C_CST_CD,
STORE$MNR2CST_COL(I).C_BEG_DT,
STORE$MNR2CST_COL(I).C_END_DT,
STORE$MNR2CST_COL(I).C_FAC,
STORE$MNR2CST_COL(I).C_AMT,
STORE$MNR2CST_COL(I).C_CUBIC_AMT,
STORE$MNR2CST_COL(I).C_LST_ACTN_DT,
STORE$MNR2CST_COL(I).C_EMP_CD
COMMIT;
EXCEPTION WHEN BULK_ERRORS THEN
OPEN C_FRT2STORE_EXC_TAB;
FETCH C_FRT2STORE_EXC_TAB INTO V_FRT2STORE_EXC_TAB;
IF C_FRT2STORE_EXC_TAB%NOTFOUND THEN
EXECUTE IMMEDIATE ('CREATE TABLE FRT2STORE_EXC AS SELECT * FROM FRT2STORE WHERE 1 = 2');
END IF;
CLOSE C_FRT2STORE_EXC_TAB;
FOR J IN 1..SQL%BULK_EXCEPTIONS.COUNT
LOOP
V_ERR_REC := SQL%BULK_EXCEPTIONS(J).ERROR_INDEX;
EXECUTE IMMEDIATE 'INSERT INTO FRT2STORE_EXC (STORE_CD,MNR_CD,FRT_FAC,DT) VALUES ('
||STORE$MNR2CST_COL(V_ERR_REC).C_STORE_CD||','
||STORE$MNR2CST_COL(V_ERR_REC).C_MNR_CD||','
||STORE$MNR2CST_COL(V_ERR_REC).C_FAC||','
||STORE$MNR2CST_COL(V_ERR_REC).C_BEG_DT||')';
END LOOP;
COMMIT;
END;
STORE$MNR2CST_COL.DELETE;
END IF;
END LOOP;
CLOSE C_FRT2STORE;
END IF;
COMMIT;
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('error:- '||SQLERRM);
END ;
Could any one tell me how to achive this requirment.
Thanks,
Sun1. Please format your code using the code tags.
2. You should never need to code create tables like this "EXECUTE IMMEDIATE ('CREATE TABLE FRT2STORE....". This is often seen when creating temporary tables in non-Oracle database but is a misunderstanding in how to do things in Oracle. You should create them outside of your plsql as permanent objects.
3. In your example, you should not need dynamic sql like this "EXECUTE IMMEDIATE 'INSERT INTO FRT2STORE_EXC...."
4. In 10gR2 / 11g, DML Error Logging might be a better solution
http://www.oracle.com/technology/oramag/oracle/06-mar/o26performance.html -
I have used save exception in a FORALL statement and the common error I return is ORA-20000.
However I get no associated error code. Is this becvause the error is user defined in the db?
The exception handler is as follows is as follows:
WHEN bulk_errors THEN
FOR j IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
LOOP
dbms_output.put_line
('Error ' || j || ' at iteration ' ||SQL%BULK_EXCEPTIONS(j).ERROR_INDEX || ' desc ' ||pono_tab(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX)||'/'||poli_tab(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX));
dbms_output.put_line(' OR Err ' ||SQLERRM(-1 * SQL%BULK_EXCEPTIONS(j).ERROR_CODE));
END LOOP;I suppose that's what I should be trying to track down...where the error is actually occurring!!
Thanks for your interest.
I will try and run the update without the bulk bind and see if the error stack is more informative.
PS.
The application is riddled with inconsistancies in how errors are handled so I am not holding out much hope!! -
Oracle 9i Problem when using multicolumn bulk update with "save exceptions"
I'm running into a problem with Oracle 9i when running a multicolumn update with "save exceptions". The problem occurs when updating 4 or more fileds. (The data being updated are 40 character text strings)
I'm updating 1000 records at a time, in bulk.
The problem goes away when I don't use "save exception" (i.e. catch the exception the normal "pre-Oracle 9i" way) or when I use "save exception" with 3 or fewer fields.
(I don't get any exceptions when running without the "save exception")
ThanksThe problem is an ORA-14403 error detected during bulk updates only when "save exception" is used with more than 3 fields being updated.
Remove the "save exception" I can update any number of fields.
or
Reduce the number of fields being updated to 3 or less and use save exceptions and the 14403 error goes away.
(I'd like to use "save exception" without having to break the "update" into two separate 3 field updates.)
Thanks,
Len -
Hello Everyone,
I have gone through the document also.
I am using dblink to get data in to table FORALL,
sometimes the database connection is lost from dblink. , i want to stop the process. and exit the loop, i am handeling the error. it raised three errors
ORA-02068
ORA-02063
ORA-02048
i read the desciption of the error, i am not sure which one is the correct to hadle. I want to handle this as special error in exception, how can i hadle this excepton.
i looks like that once the db connection is lost forall stops execution. is that correct? please correct if if i am wrong.
Please help me.
thank you in advanceYou will want to map these exceptions using PRAGMA EXCEPTION_INIT and capture them as a user defined exception. You will find an example of doing this here:
http://www.psoug.org/reference/exception_handling.html -
DECLARE
TYPE empid_tab IS TABLE OF emp1%ROWTYPE;
emp_sr empid_tab;
-- CREATE AN EXCEPTION HANDLER FOR ORA-24381
ERRORS NUMBER;
dml_errors EXCEPTION;
v_err_no VARCHAR2 (200);
v_err_message VARCHAR2 (200);
PRAGMA EXCEPTION_INIT (dml_errors, -24381);
BEGIN
SELECT *
BULK COLLECT INTO emp_sr
FROM emp1
WHERE hiredate > '30-MAY-80';
FORALL i IN 1 .. emp_sr.COUNT SAVE EXCEPTIONS
INSERT INTO emp_temp123
VALUES emp_sr (i);
--if any dupliacte records are inserting onto the emp_temp123 then it will give error as unique constraint violated
-- IF ANY ERRORS OCCURRED DURING THE FORALL SAVE EXCEPTIONS,
-- A SINGLE EXCEPTION IS RAISED WHEN THE STATEMENT COMPLETES.
EXCEPTION
WHEN dml_errors
THEN -- NOW WE FIGURE OUT WHAT FAILED AND WHY.
ERRORS := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.put_line ('Number of statements that failed: ' || ERRORS);
FOR i IN 1 .. ERRORS
LOOP
DBMS_OUTPUT.put_line ( 'Error #'
|| i
|| ' occurred during '
|| 'iteration #'
|| SQL%BULK_EXCEPTIONS (i).ERROR_INDEX
DBMS_OUTPUT.put_line ( 'Error message is '
|| SQLERRM
(-SQL%BULK_EXCEPTIONS (i).ERROR_CODE)
v_err_no := SQL%BULK_EXCEPTIONS (i).ERROR_INDEX;
v_err_message := SQLERRM (-SQL%BULK_EXCEPTIONS (i).ERROR_CODE);
INSERT INTO errorlog
(ID, MESSAGE
VALUES (v_err_no, v_err_message
COMMIT;
END LOOP;
END;
ID MESSAGE
5 ORA-00001: unique constraint (.) violated
6 ORA-00001: unique constraint (.) violated
7 ORA-00001: unique constraint (.) violated
8 ORA-00001: unique constraint (.) violated
9 ORA-00001: unique constraint (.) violated
10 ORA-00001: unique constraint (.) violated
11 ORA-00001: unique constraint (.) violated
12 ORA-00001: unique constraint (.) violated
13 ORA-00001: unique constraint (.) violated
3 ORA-00001: unique constraint (.) violated
4 ORA-00001: unique constraint (.) violated
here its only inserting the erros only but i want to insert the error records ie all columns of error record into another table named emp_err .how to do it.user10447332 wrote:
here its only inserting the erros only but i want to insert the error records ie all columns of error record into another table named emp_err .how to do it.If Saubhik's solution is not the one you want you'll have to manually refer back to the collection for the records that have errors, then extract those values and do whatever you want with them. -
PL SQL with multiple inserts, how to continue after exception is raised
Hi,
I have a simple PL SQL function with various inserts. ex:
Insert Into "DI01"."DUA_DIM_UNITE_ADMIN" (Ide_Unite_Admin_Sk, Num_Unite_Admin, Des_Unite_Admin) Values ('-1', '00000000', 'Défaut');
INSERT INTO "DI01"."DUA_DIM_UNITE_ADMIN" (IDE_UNITE_ADMIN_SK, NUM_UNITE_ADMIN, DES_UNITE_ADMIN) VALUES ('-2', 'S. O.', 'Sans Objet');
Insert Into "DI01"."DCU_DIM_CATGR_UNSPS" (Ide_Catgr_Sk, Num_Code, Des_Code, Num_Catgr, Des_C.........
I want to be able to run the function multiple times, and have all the inserts executed everytime, even if I get a ORA-00001 unique constraint (string.string) violated error in on of the inserts. That means that if I get an error in the first insert, I want the function to continue running and executing the consecutive inserts.
I though of including each insert in a different block, like:
BEGIN
Insert......
When Exception then null;
END;
BEGIN
Insert......
When Exception then null;
END;
But I have at least 50 inserts, so the final code becomes huge.
Another solution is to use merge inseat of insert, but the code seems too complex for such a simple task.
Is there any other solution for this that I am not seeing?
Thank you for your time,
Joao MoreiraYou can use DML error logging approach or FORALL SAVE EXCEPTIONS.
Since you didn't mention the version I assume you are using 11g.
Below is the sample code for DML error logging mechanism
SQL> select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> DROP TABLE tableA;
Table dropped.
SQL> DROP TABLE Err$_tableA;
Table dropped.
SQL>
SQL> CREATE TABLE tableA
2 (
3 col1 NUMBER PRIMARY KEY,
4 col2 NUMBER,
5 col3 VARCHAR2 (10)
6 );
Table created.
SQL>
SQL> -- Create error log table
SQL>
SQL> BEGIN
2 DBMS_ERRLOG.create_error_log (dml_table_name => 'TABLEA');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 FOR i IN (SELECT 1 AS col1 FROM DUAL
3 UNION ALL
4 SELECT 1 FROM DUAL)
5 LOOP
6 INSERT INTO tableA (col1)
7 VALUES (i.col1)
8 LOG ERRORS INTO Err$_tableA REJECT LIMIT UNLIMITED;
9 END LOOP;
10
11 COMMIT;
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> column column_name format a30
SQL> set linesize 300
SQL> select * from tableA;
SQL> select * from err$_tablea;
Thanks,
GPU -
Inserting rows in table while logging errors...Urgent
Hi all,
i want to insert rows from temp table to main table.
if temp table contains 100 rows.then all rows must be inserted
in main table.if their is any exception while insertion,
insertion must nt stop and erroring rows along with error no must be inserted in
error log table.
How to do this ?
i used forall save exceptions to achieve this .
but ws able to save only error no. but not errroing rows in error log table.
is there any efficient way to achieve this?
can forall be modified in way that it inserts erroring rows also?????Hi,
1.) does dbms_errorlog works fine in this case?If all of your 807 tables having same columns then i think it will work (NOT TESTED).
By the way are you also trying to insert rows for all tese 807 tables in a single PL/SQL block?
Please post how you are trying to insert then we can think about it,
Oracle ERROR_LOG table allows us to have any number of columns.
From the Oracle Docs:
The number of columns in this part of the error logging table can be zero, one, or more, up to the number of columns in the DML table. If a column exists in the error logging table that has the same name as a column in the DML table, the corresponding data from the offending row being inserted is written to this error logging table column. If a DML table column does not have a corresponding column in the error logging table, the column is not logged. If the error logging table contains a column with a name that does not match a DML table column, the column is ignored.
Regards -
How to capture the record value, when an error occurs
Hi , can you please help us in achieving the below requirement.
i have source with 10 accounts , i have to update the 5 target tables for the 10 accounts, i am using a for loop to do insert/update operations.
when an primary key/unique constraint error occurs while doing the insert/update operations, i want to catpure that account number along with the
error message and store in a table.
right now i am using sqlerrm,sqlcode in my exception block to capture the oracle error code and error message,i need to capture the account number along with this message. please tell me how to achieve this ...
thanksif you want to log the error in the table and keep going with the rest of them you might want to check out bulk collection exception handling.
http://psoug.org/reference/array_processing.html
CREATE OR REPLACE PROCEDURE forall_errors IS
TYPE myarray IS TABLE OF tmp_target%ROWTYPE;
l_data myarray;
CURSOR c IS
SELECT table_name, num_rows
FROM all_tables;
errors PLS_INTEGER;
dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(dml_errors, -24381);
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO l_data LIMIT 100;
-- SAVE EXCEPTIONS means don't stop if some DELETES fail
FORALL i IN 1..l_data.COUNT SAVE EXCEPTIONS
INSERT INTO tmp_target VALUES l_data(i);
-- If any errors occurred during the FORALL SAVE EXCEPTIONS,
-- a single exception is raised when the statement completes.
EXIT WHEN c%NOTFOUND;
END LOOP;
EXCEPTION
WHEN dml_errors THEN
errors := SQL%BULK_EXCEPTIONS.COUNT;
dbms_output.put_line('Number of DELETE statements that
failed: ' || errors);
FOR i IN 1 .. errors
LOOP
dbms_output.put_line('Error #' || i || ' at '|| 'iteration
#' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
dbms_output.put_line('Error message is ' ||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
WHEN OTHERS THEN
RAISE;
END forall_errors;
/ -
Converting PL/SQL with OE S Fields for 11i
We recently moved to 11i and I am having trouble converting a PL/SQL report. This is part of an exception report (below) that we have and I am not exactly sure how to convert it in 11i to do what it did in 11.0.3. Particularily I am not sure about how to convert the "S" fields, if someone could provide some guidance that would be great. I have marked the lines I am not sure of with DON'T KNOW. Thanks, Joe.
SELECT
soh.order_number
, sol.s2_date --Pick Release Release Date DON'T KNOW
, usr.user_name
, sol.line_number
FROM oe.so_headers_all soh --WILL BE ONT.OE_ORDER_HEADERS_ALL
, oe.so_lines_all sol --WILL BE ONT.OE_ORDER_LINES_ALL
, apps.fnd_user usr
WHERE 1=1
AND soh.header_id = sol.header_id
AND soh.created_by = usr.user_id
AND (sol.s2 = 4 -- line is pick released DON'T KNOW
AND sol.s4 = 18 -- ship confirm Eligible DON'T KNOW
AND soh.s6 != 10 --not closed WILL BE AND SOH FLOW_STATUS_CODE != 'CLOSED'
) -- line is pick released, ship confirm confirmed, not closed
AND soh.order_type_id != 1000
AND SOL.S2_DATE < sysdate-5 --Pick Release Release Date DON'T KNOWYou can use DML error logging approach or FORALL SAVE EXCEPTIONS.
Since you didn't mention the version I assume you are using 11g.
Below is the sample code for DML error logging mechanism
SQL> select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> DROP TABLE tableA;
Table dropped.
SQL> DROP TABLE Err$_tableA;
Table dropped.
SQL>
SQL> CREATE TABLE tableA
2 (
3 col1 NUMBER PRIMARY KEY,
4 col2 NUMBER,
5 col3 VARCHAR2 (10)
6 );
Table created.
SQL>
SQL> -- Create error log table
SQL>
SQL> BEGIN
2 DBMS_ERRLOG.create_error_log (dml_table_name => 'TABLEA');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 FOR i IN (SELECT 1 AS col1 FROM DUAL
3 UNION ALL
4 SELECT 1 FROM DUAL)
5 LOOP
6 INSERT INTO tableA (col1)
7 VALUES (i.col1)
8 LOG ERRORS INTO Err$_tableA REJECT LIMIT UNLIMITED;
9 END LOOP;
10
11 COMMIT;
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> column column_name format a30
SQL> set linesize 300
SQL> select * from tableA;
SQL> select * from err$_tablea;
Thanks,
GPU -
Getting the constraint name with sql%bulk_exceptions
Hello folks,
Is there any way to get the constraint name that was violated using sql%bulk_exceptions.
I've a parent table and it's two children tables. When I try to delete from parent using forall, save exceptions, I want to know what constraint violated at what iteration of a bulk operation.
I've following script.
set serveroutput on
drop table chld;
drop table chld2;
drop table prnt;
create table prnt(n number primary key);
insert into prnt select level from dual connect by level<11;
create table chld(cn number references prnt(n));
insert into chld select level from dual connect by level<3;
create table chld2(cn number references prnt(n));
insert into chld2 select level*3 from dual connect by level<3;
select * from prnt;
select * from chld;
select * from chld2;
commit;
declare
type t_prnt_obj is table of prnt.n%type index by pls_integer;
t_prnt_tab t_prnt_obj;
l_exp_cnt integer;
begin
select n bulk collect into t_prnt_tab from prnt order by n;
dbms_output.put_line('t_prnt_tab.count -- '||t_prnt_tab.count);
forall i in t_prnt_tab.first .. t_prnt_tab.last save exceptions
delete prnt where n = t_prnt_tab(i);
exception
when others
then
l_exp_cnt := sql%bulk_exceptions.count;
dbms_output.put_line('Total exceptions:'|| l_exp_cnt);
for k in 1 .. l_exp_cnt
loop
dbms_output.put_line('Error '||k|| ' - Collection Index: '||sql%bulk_exceptions(k).error_index||' - Error Code: '|| sql%bulk_exceptions(k).error_code||' - Message: '||SQLERRM(- sql%bulk_exceptions(k).error_code) );
end loop;
end;I get the output as below:
t_prnt_tab.count -- 10
Total exceptions:4
Error 1 - Collection Index: 1 - Error Code: 2292 - Message: ORA-02292: integrity constraint (.) violated - child record found
Error 2 - Collection Index: 2 - Error Code: 2292 - Message: ORA-02292: integrity constraint (.) violated - child record found
Error 3 - Collection Index: 3 - Error Code: 2292 - Message: ORA-02292: integrity constraint (.) violated - child record found
Error 4 - Collection Index: 6 - Error Code: 2292 - Message: ORA-02292: integrity constraint (.) violated - child record foundInstead, I want to get in output with the constraint_name added. Like below:
t_prnt_tab.count -- 10
Total exceptions:4
Error 1 - Collection Index: 1 - Error Code: 2292 - Message: ORA-02292: integrity constraint (GK.CP_FK) violated - child record found
Error 1 - Collection Index: 1 - Error Code: 2292 - Message: ORA-02292: integrity constraint (GK.CP_FK) violated - child record found
Error 1 - Collection Index: 1 - Error Code: 2292 - Message: ORA-02292: integrity constraint (GK.C2P_FK) violated - child record found
Error 1 - Collection Index: 1 - Error Code: 2292 - Message: ORA-02292: integrity constraint (GK.C2P_FK) violated - child record foundIs it possible, if so how do I get it?
Thanks in advance for you help.
GirishThis is phenomenal, Manik. It surely eased the work am doing at the moment.
Thanks to you and many more to, Tom!
Cheers!
Girish
Maybe you are looking for
-
What if you can't sign in to your order from Apple Store?
I can't sign in to Apple Store with my Apple ID; I can sign in everywhere else except there. I have a $1,151.00 order pending, and it's shown there when I enter order number, but then to make changes or correct the address (and many other things) it
-
Okay. I need help.. My computer crashed and I know that I should have had a back but did not. Any way, now how can I get my music back on my computer from my IPOD? Thank you all for the help....
-
what do if itunes say it that my ipod touch 4g 5.1 firmware corrupt when I try to restore it
-
Physical inventory, LX16 ,table update LQUA-IDATU
Hi Experts, When execute LX16 for PI, is this process updates last inventory date at bin level or quant level table ? After completing LX16 process, and continue to execute Cycle count in LICC , the same materials in which physical inventory were com
-
Need help with cannon RAW photos
Please help- let my employee go and nearly 100 photos of my products were left on my hard drive, but I can not get them to open. They are somehow jacked up (show a different icon than they did). They have no previous version, and absolutely NOTHING