2014-10-16 104 views
0

我想写一个函数,将随机的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' 
+1

你为什么不故意做一个故事并阅读错误信息? – 2014-10-16 12:08:28

+0

@DanBracuk UUID首次碰撞需要一些时间。 – ceving 2014-10-16 12:15:41

回答

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; 
+0

谢谢,但环路如何? – ceving 2014-10-16 12:05:45

+0

[“GOTO语句不能分支到异常处理程序中,而且,GOTO语句不能从异常处理程序分支到当前块中。”](http://docs.oracle.com/cd/B10500_01/appdev.920/ a96624/07_errs.htm) – 2014-10-16 12:07:02

+0

@ceving:查看已更新的答案。 – 2014-10-16 12:09:50

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

分享和享受。