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

Но я не могу понять, правильное имя исключения, которое возникает, когда первичный ключ Ограничить нарушается. Кто-нибудь знает?

Update

Я попытался 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

Почему вы не делаете это специально и не читаете сообщение об ошибке? –

+0

@DanBracuk Требуется некоторое время, пока UUID не получит свое первое столкновение. – ceving

ответ

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

+0

["Оператор GOTO не может входить в обработчик исключений. Кроме того, оператор GOTO не может входить из обработчика исключений в текущий блок."] (Http://docs.oracle.com/cd/B10500_01/appdev.920/ a96624/07_errs.htm) –

+0

@ceving: см. обновленный ответ. –

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; 

Делитесь и наслаждайтесь.

Смежные вопросы