即使使用例外,“ORA-00001:违反了唯一约束”

时间:2013-12-04 12:42:05

标签: sql oracle exception for-loop plsql

我的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;
/

1 个答案:

答案 0 :(得分:0)

DUP_VAL_ON_INDEX异常不能直接用于函数;

根据Oracle文档,DUP_VAL_ON_INDEX异常不会传播

运行时的异常

查询中的

:“因为某些SQL函数在内部使用此异常来发信号

他们是

完成后,如果在

中提升它,则不应该依赖于传播的异常

的功能

作为查询的一部分调用。“