指示主键约束违规的异常名称是什么?

时间:2014-10-16 11:54:24

标签: sql oracle plsql exception-handling

我想编写一个将随机UUID插入表中的函数。成功插入UUID后,该函数应返回UUID。在主键冲突的情况下,我希望该函数尝试另一个UUID,直到它成功。

到目前为止我所拥有的:

create or replace 
function new_object_id return raw is
  v_oid RAW(16);
begin
<<next_uuid>>
  v_oid := random_uuid();
  insert into object (object_id) values (v_oid);
  commit;
  exception
    when ?primary_key_constrain_failure? then goto next_uuid
  end;
  return v_oid;
end new_object_id;

但我无法找出异常的正确名称,这在违反主键约束时会发生。有人知道吗?

更新

我尝试了dup_val_on_index,但我仍然遇到循环问题:

create or replace 
function new_object_id return raw is
  v_oid RAW(16);
begin
<<next_uuid>>
  v_oid := random_uuid();
  insert into object (object_id) values (v_oid);
  commit;
  return (v_oid);
exception
  when DUP_VAL_ON_INDEX then goto next_uuid;
end new_object_id;

当我编译它时,我收到错误:

Error(11,30): PLS-00375: illegal GOTO statement; this GOTO cannot branch to label 'NEXT_UUID'

3 个答案:

答案 0 :(得分:2)

根据this,它是DUP_VAL_ON_INDEX

完整的工作测试:

create table x
( y number(15,0)
, constraint x_pk primary key (y)
)
;

begin
  insert into x (y) values (1);
exception
  when dup_val_on_index
  then
    dbms_output.put_line('ARGH!!!');
end;

对于第2部分,使用封装begin ... end块:

begin
  <<test>>
  begin
    insert into x values (1);
    exception
      when dup_val_on_index then goto test; -- I know, a loop, but it is for the demo
    end;
end;

答案 1 :(得分:0)

现在编译:

create or replace 
function new_object_id return raw is
  v_oid RAW(16);
begin
<<next_uuid>>
  begin
    v_oid := random_uuid();
    insert into object (object_id) values (v_oid);
    commit;
    return (v_oid);
  exception
    when dup_val_on_index then goto next_uuid;
  end;
end new_object_id;

答案 2 :(得分:0)

要使用LOOP尝试:

create or replace function new_object_id return raw is
  v_oid RAW(16);
begin
  LOOP
    begin
      v_oid := random_uuid();
      insert into object (object_id) values (v_oid);
      EXIT;
    exception
      when dup_val_on_index then 
        NULL;  -- do nothing, roll around to top of LOOP again
    end;
  END LOOP;

  commit;

  return (v_oid);
end new_object_id;

分享并享受。