2009-01-13 3 views
32

Decir que tengo un bloque de Oracle PL/SQL que inserta un registro en una tabla y la necesidad de recuperarse de un error de restricción único, de esta manera:¿Cómo atrapar un error de restricción único en un bloque PL/SQL?

begin 
    insert into some_table ('some', 'values'); 
exception 
    when ... 
     update some_table set value = 'values' where key = 'some'; 
end; 

¿Es posible sustituir los puntos suspensivos para algo con el fin de atrapar un error de restricción único?

+0

Para utilizar las excepciones de esta manera es un poco lento debido a elevar excepciones toma un montón de tiempo. Prueba fusionar – tuinstoel

+1

De acuerdo. Pero tenga en cuenta que este ejemplo fue solo uno de muchos posibles casos de uso. La pregunta realmente es "¿cuál es la identificación del error de restricción único?". Es por eso que voté la respuesta de William pero acepté la de Ricardo. –

+2

Las excepciones en el código PL/SQL no son tan costosas como en los lenguajes administrados o de alto nivel (C#, Java). En una aplicación DB la "lentitud" real es causada por el acceso db, un costo de excepción PL/SQL es insignificante en este contexto –

Respuesta

55
EXCEPTION 
     WHEN DUP_VAL_ON_INDEX 
     THEN 
     UPDATE 
+2

¿cómo se puede escribir el valor que está causando el problema? –

+0

Selecciona esta .. http://www.orafaq.com/forum/t/13889/2/ –

11

Sospecho que la condición que busca es DUP_VAL_ON_INDEX

EXCEPTION 
    WHEN DUP_VAL_ON_INDEX THEN 
     DBMS_OUTPUT.PUT_LINE('OH DEAR. I THINK IT IS TIME TO PANIC!') 
+0

¿cómo se puede escribir el valor que está causando el problema? –

+0

cuando se detecta la excepción, ejecute una nueva consulta que solo selecciona los duplicados y los informa. – EvilTeach

+0

puede hacer eso antes de ejecutar la consulta? –

24

Estoy seguro de que tiene sus razones, pero por si acaso ... también se debe considerar el uso de un "Combinar" consulta en su lugar:

begin 
    merge into some_table st 
    using (select 'some' name, 'values' value from dual) v 
    on (st.name=v.name) 
    when matched then update set st.value=v.value 
    when not matched then insert (name, value) values (v.name, v.value); 
end; 

(modificó el anterior para estar en el bloque begin/end; obviamente, se puede ejecutar forma independiente del procedimiento también).

+1

Esto ayuda con este caso de uso específico, pero fue sólo un ejemplo. La pregunta es realmente acerca de la identificación de un error de restricción único, así que estoy votando esta respuesta porque de hecho es útil, pero la de Ricardo será la aceptada. –

+1

La respuesta de Ricardo fue la correcta llamada excepción, pero creo que la sugerencia de William ayudará a más personas en el largo plazo. –

Cuestiones relacionadas