Reputation: 546
I am trying to insert values into sql table, but I am getting this error in sql query
SQL Error: ORA-00001: unique constraint (uniqueKey) violated
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.
Is there a way to skip this error and continue insert. Something like this
try
insert query
catch (unique constraint error)
continue inserting other values
Upvotes: 3
Views: 19820
Reputation: 2615
simple sample is insert in for loop
and ignore exceptions:
begin
for rc in (select * from <your query> loop
begin
insert into t1(...) values (...);
exceptions when others then
null;--ignore any exceptions do nothing
end;
end loop;
end
other sample - same idea but use FORALL
bulk operation and SAVE EXCEPTIONS
declare
cursor C is
select ID, OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID,
decode( mod(rownum,100000), 1, rpad('*',20,'*'), OBJECT_TYPE ) object_type,
CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS, TEMPORARY, GENERATED, SECONDARY
from big_table;
type array is table of c%rowtype;
l_data array;
dml_errors EXCEPTION;
PRAGMA exception_init(dml_errors, -24381);
l_errors number;
l_errno number;
l_msg varchar2(4000);
l_idx number;
begin
open c;
loop
fetch c bulk collect into l_data limit 100;
begin
forall i in 1 .. l_data.count SAVE EXCEPTIONS
insert into t2 values l_data(i);
exception
when DML_ERRORS then
l_errors := sql%bulk_exceptions.count;
for i in 1 .. l_errors
loop
l_errno := sql%bulk_exceptions(i).error_code;
--do smth with the exceptions
end loop;
end;
exit when c%notfound;
end loop;
close c;
end;
more information see on AskTom and OraMagazine
https://asktom.oracle.com/pls/asktom/f?p=100:11:0%3A%3A%3A%3AP11_QUESTION_ID:1422998100346727312
http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html
Upvotes: 0
Reputation: 5809
There exists hint ignore_row_on_dupkey_index(<table name>, <unique index name>)
.
HUSQVIK@hq_pdb_tcp> CREATE TABLE tmp (val NUMBER CONSTRAINT pk_tmp PRIMARY KEY);
Table created.
HUSQVIK@hq_pdb_tcp> INSERT /*+ ignore_row_on_dupkey_index(tmp, pk_tmp) */ INTO tmp (val) SELECT 1 FROM DUAL CONNECT BY LEVEL <= 3;
1 row created.
See that I insert three values of 1 and only one row was created.
Upvotes: 10
Reputation: 27294
There is a LOG ERRORS
clause which allows you to log the rows that cause errors in to an error table - this error table is created using a DBMS package:
DBMS_ERRLOG.CREATE_ERROR_LOG(table_being_inserted_into ,name_of_table_for_errors ,NULL,NULL,TRUE);
https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_errlog.htm
Function Signature:
DBMS_ERRLOG.CREATE_ERROR_LOG (
dml_table_name IN VARCHAR2,
err_log_table_name IN VARCHAR2 := NULL,
err_log_table_owner IN VARCHAR2 := NULL,
err_log_table_space IN VARCHAR2 := NULL,
skip_unsupported IN BOOLEAN := FALSE);
Then in your insert statement you end it with a log errors clause:
LOG ERRORS INTO your_error_table_name ( 'description of your choosing' ) REJECT LIMIT UNLIMITED;
You can choose to accept a reject limit of a fixed number, allowing you to specify in effect a tolerance to errors before it throws a real error instead of just allowing the row to be place in an error table.
Upvotes: 0