2014-10-16 76 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; 

分享和享受。