Oracle ORA-00001:插入0行时违反了唯一约束
我正在尝试将0行插入到具有唯一约束的表中,我得到ORA-00001:违反了唯一约束 下面是我用来很好地捕捉问题的PL/SQL块Oracle ORA-00001:插入0行时违反了唯一约束,oracle,sql-insert,oracle12c,unique-constraint,dml,Oracle,Sql Insert,Oracle12c,Unique Constraint,Dml,我正在尝试将0行插入到具有唯一约束的表中,我得到ORA-00001:违反了唯一约束 下面是我用来很好地捕捉问题的PL/SQL块 declare l_cnt number; begin set transaction isolation level serializable; select count(*) into l_cnt from test_view; dbms_output.put_line('count = ' || to_char(l_cnt));
declare
l_cnt number;
begin
set transaction isolation level serializable;
select count(*) into l_cnt from test_view;
dbms_output.put_line('count = ' || to_char(l_cnt));
insert into <table>(<columns>)
select <columns> from test_view
log errors ('run1')
reject limit 0
;
dbms_output.put_line('success');
exception
when others then
dbms_output.put_line('ERRROR!');
dbms_output.put_line(sqlerrm);
rollback;
end;
/
更新2
我能够重现这种行为
CREATE TABLE A(ID NUMBER PRIMARY KEY)
/
CREATE FUNCTION F(ID_ NUMBER) RETURN NUMBER
AS
L_ID NUMBER;
BEGIN
SELECT ID INTO L_ID FROM A WHERE ID = ID_;
RETURN L_ID;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
/
BEGIN
DBMS_ERRLOG.CREATE_ERROR_LOG('A');
END;
/
BEGIN
INSERT INTO A VALUES (1);
INSERT INTO A SELECT 1 FROM DUAL WHERE F(1) IS NULL
LOG ERRORS INTO ERR$_A;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
SELECT * FROM ERR$_A
/
这一切归结为查询从函数内部修改的表。函数抛出ORA-04091:表A正在变化,触发器/函数可能看不到它
,但代码捕获所有异常并返回null
显然,从发生变异的表中进行选择是非零的,必须固定
我很生气,因为我数不清有多少次,当其他人返回null时,我告诉同事们停止使用
异常。这又是一个例子,它完全掩盖了问题,我花了一整天的时间来解释它。Select返回了0行,没问题
然而,当向表中插入行时,我们实际上是通过一个函数查询同一个表。返回的函数ORA-04091:表A正在变异,触发器/函数可能看不到它
,但它被捕获在异常块中,并返回了null
。这导致查询返回行
当其他人返回null时,切勿使用异常<代码>拒绝限制0
意味着不允许出现错误,因此显然它将在第一个错误时停止。您是否正在寻找拒绝无限限制
?不,我希望没有错误。我使用日志错误只是为了查看表中的内容。我的问题是表中应该没有插入任何内容,查询返回0行…请检查select count(*)
。由于索引损坏而导致错误的计数(*)
并不少见。您还应该意识到,如果不显示视图的一些细节,就无法获得有意义的完整响应。例如,我怀疑如果你选择*
你会看到一些数据。@MarmiteBomber感谢你指出计数(*)
可能会给出与选择所有值不同的结果。但是,即使我使用完全相同的查询将所有数据插入到不同的表中,我也可以看到有0行(请参见我更新的问题)。。。如果我从testx\u视图中选择了*,我会看到0条记录…请显示约束。
declare
l_cnt number;
begin
set transaction isolation level serializable;
insert into testx_table
select * from testx_view d;
select count(*) into l_cnt from testx_table;
dbms_output.put_line('count = ' || to_char(l_cnt));
insert into <table>(<columns>)
select * from testx_view d
log errors ('run2')
reject limit 0;
dbms_output.put_line('success');
exception
when others then
dbms_output.put_line('ERRROR!');
dbms_output.put_line(sqlerrm);
rollback;
end;
/
CREATE TABLE A(ID NUMBER PRIMARY KEY)
/
CREATE FUNCTION F(ID_ NUMBER) RETURN NUMBER
AS
L_ID NUMBER;
BEGIN
SELECT ID INTO L_ID FROM A WHERE ID = ID_;
RETURN L_ID;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
/
BEGIN
DBMS_ERRLOG.CREATE_ERROR_LOG('A');
END;
/
BEGIN
INSERT INTO A VALUES (1);
INSERT INTO A SELECT 1 FROM DUAL WHERE F(1) IS NULL
LOG ERRORS INTO ERR$_A;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
SELECT * FROM ERR$_A
/