“ORA-00001:违反了唯一约束”,即使使用异常
Posted
技术标签:
【中文标题】“ORA-00001:违反了唯一约束”,即使使用异常【英文标题】:"ORA-00001: unique constraint violated" even when using an exception 【发布时间】:2013-12-04 12:42:04 【问题描述】:我的 PL-SQL 代码有问题,因为我有一个将行插入表的 for 循环,问题是有时会尝试插入重复的值,所以我收到 ORA-00001 错误。 我添加了一个例外来避免这种情况,但它似乎不起作用......你能帮帮我吗? :)
这是我的代码(出错的那个):
if (x = 1) then
if (proyec(alumno_rec.alumno_codigo, alumno_rec.plan_codigo, asignatura_rec.asignatura_codigo) is not null) then
begin
insert into proyeccion (alumno_codigo, asignatura_codigo, proyeccionestado_codigo)
values (alumno_rec.alumno_codigo, proyec(alumno_rec.alumno_codigo, alumno_rec.plan_codigo, asignatura_rec.asignatura_codigo), 1);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
update proyeccion set asignatura_codigo=proyec(alumno_rec.alumno_codigo, alumno_rec.plan_codigo, asignatura_rec.asignatura_codigo)
where alumno_codigo=alumno_rec.alumno_codigo;
end;
end if;
end if;
这是上面提到的功能:
create or replace function proyec(cod_alum alumno.alumno_codigo%type, plan_cod alumno.plan_codigo%type, cod_asig asignatura.asignatura_codigo%type)
return number is
asig number;
begin
select asignatura_codigo
into asig
from requisito
where requisito_codigo=cod_asig and
plan_codigo=plan_cod and
asignatura_codigo in (select asignatura_codigo from matricula where alumno_codigo=cod_alum);
return asig;
end;
/
这里是完整的主要代码供参考:
set serveroutput on size 10000
declare
cursor alum is
select alumno_codigo, plan_codigo
from alumno
where alumno_codigo in (select alumno_codigo from matricula where alumno_codigo = alumno.alumno_codigo);
cursor asig is
select asignatura_codigo
from asignatura;
x number;
begin
for alumno_rec in alum loop
update alumno set alumno_promedio=prom(alumno_rec.alumno_codigo) where alumno_codigo=alumno_rec.alumno_codigo;
update alumno set alumno_semestre=sem(cred(alumno_rec.alumno_codigo)) where alumno_codigo=alumno_rec.alumno_codigo;
if (perdida(alumno_rec.alumno_codigo)>1) then
update alumno set alumnoestado_codigo=3 where alumno_codigo=alumno_rec.alumno_codigo;
end if;
for asignatura_rec in asig loop
select alumnoestado_codigo into x from alumno where alumno_codigo=alumno_rec.alumno_codigo;
if (perdida2(alumno_rec.alumno_codigo, asignatura_rec.asignatura_codigo)=2) then
update alumno set alumnoestado_codigo=3 where alumno_codigo=alumno_rec.alumno_codigo;
elsif (perdida2(alumno_rec.alumno_codigo, asignatura_rec.asignatura_codigo)>2) then
update alumno set alumnoestado_codigo=4 where alumno_codigo=alumno_rec.alumno_codigo;
elsif x is null then
update alumno set alumnoestado_codigo=1 where alumno_codigo=alumno_rec.alumno_codigo;
end if;
if (x = 1) then
if (proyec(alumno_rec.alumno_codigo, alumno_rec.plan_codigo, asignatura_rec.asignatura_codigo) is not null) then
begin
insert into proyeccion (alumno_codigo, asignatura_codigo, proyeccionestado_codigo)
values (alumno_rec.alumno_codigo, proyec(alumno_rec.alumno_codigo, alumno_rec.plan_codigo, asignatura_rec.asignatura_codigo), 1);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
update proyeccion set asignatura_codigo=proyec(alumno_rec.alumno_codigo, alumno_rec.plan_codigo, asignatura_rec.asignatura_codigo)
where alumno_codigo=alumno_rec.alumno_codigo;
end;
end if;
end if;
end loop;
end loop;
end;
/
【问题讨论】:
也许更新语句会生成 ORA-00001? 就像 Rene 说的 - 检查你在桌子上的所有独特约束。我敢打赌 asignatura_codigo 列在其中之一中,并且您的更新语句打破了约束。 【参考方案1】:DUP_VAL_ON_INDEX 异常不能直接用在函数中;
根据 Oracle 文档,DUP_VAL_ON_INDEX 异常不会传播
运行异常
在查询中:“因为某些 SQL 函数在内部使用此异常来发出信号
那个
他们是
已完成,如果您在
中引发此异常,则不应依赖该异常被传播函数是
作为查询的一部分调用。”
【讨论】:
如果你想让它在函数中传播,请声明异常以上是关于“ORA-00001:违反了唯一约束”,即使使用异常的主要内容,如果未能解决你的问题,请参考以下文章
即使在使用 SingleChildScrollView() 包装 column() 后也无法在小部件上滚动