指示违反主键约束的异常的名称是啥?

Posted

技术标签:

【中文标题】指示违反主键约束的异常的名称是啥?【英文标题】:What is the name of the exception indicating a primary key constrain violation?指示违反主键约束的异常的名称是什么? 【发布时间】:2014-10-16 11:54:24 【问题描述】:

我想编写一个将随机 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'

【问题讨论】:

你为什么不故意做一个并阅读错误信息? @DanBracuk UUID 第一次发生冲突需要一些时间。 【参考方案1】:

根据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;

【讨论】:

谢谢,但是循环呢? "A GOTO statement cannot branch into an exception handler. Also, a GOTO statement cannot branch from an exception handler into the current block." 谢谢!我不知道为什么我的 goto 版本与内部开始的版本不同,但它似乎工作。【参考方案2】:

现在编译:

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;

【讨论】:

【参考方案3】:

要使用 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;

分享和享受。

【讨论】:

以上是关于指示违反主键约束的异常的名称是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate主键生成策略strategy = "increment"报错违反唯一性约束

违反主键约束查询

System.Data.SqlClient.SqlException:'违反主键约束

违反主键约束,多个用户

更新时SQL违反主键约束

Hibernate 和 HSQLDB 违反主键完整性约束