Personalizar excepciones PL / SQL en Oracle
-
21-09-2019 - |
Pregunta
Con frecuencia me encontré haciendo algunas funciones para insertar / eliminar / actualizar en una o más tablas y he visto algunas excepciones esperados sido atendidos, como no_data_found
, dupl_val_on_index
, etc. Para una inserción como esta:
create or replace FUNCTION "INSERT_PRODUCTS" (
a_supplier_id IN FORNECEDOR.ID_FORNECEDOR%TYPE,
a_prodArray IN OUT PRODTABLE
)
RETURN NUMBER IS
v_error_code NUMBER;
v_error_message VARCHAR2(255);
v_result NUMBER:= 0;
v_prod_id PRODUTO.ID_PROD%TYPE;
v_supplier FORNECEDOR%ROWTYPE;
v_prodInserted PROD_OBJ;
newList prodtable := prodtable();
BEGIN
SELECT FORNEC_OBJ(ID_FORNECEDOR,NOME_FORNECEDOR,MORADA,ARMAZEM,EMAIL,TLF,TLM,FAX) into v_supplier from fornecedor where id_fornecedor = a_supplier_id;
FOR i IN a_prodArray.FIRST .. a_prodArray.LAST LOOP
INSERT INTO PRODUTO (PRODUTO.ID_PROD,PRODUTO.NOME_PROD,PRODUTO.PREC_COMPRA_PROD,PRODUTO.IVA_PROD,PRODUTO.PREC_VENDA_PROD,PRODUTO.QTD_STOCK_PROD,PRODUTO.QTD_STOCK_MIN_PROD)
VALUES (S_PRODUTO.nextval,a_prodArray(i).NOME_PROD,a_prodArray(i).PREC_COMPRA_PROD,a_prodArray(i).IVA_PROD,NULL,NULL,NULL);
/* If the above insert didn't failed, we can insert in weak entity PROD_FORNECIDO. */
SELECT ID_PROD into v_prod_id from PRODUTO where NOME_PROD = a_prodArray(i).NOME_PROD;
INSERT INTO PROD_FORNECIDO VALUES (a_supplier_id, v_prod_id,a_prodArray(i).PREC_COMPRA_PROD);
SELECT PROD_OBJ(ID_PROD,NOME_PROD,PREC_COMPRA_PROD,PREC_VENDA_PROD,QTD_STOCK_PROD,QTD_STOCK_MIN_PROD,IVA_PROD) into v_prodInserted from PRODUTO where ID_PROD= v_prod_id;
a_prodarray(i).ID_PROD := v_prod_id;
END LOOP;
INSERT INTO FORNECPRODS VALUES (a_supplier_id,v_supplier, a_prodarray);
v_result:= 1;
RETURN v_result;
COMMIT;
Exception
When no_data_found then
v_error_code := 0;
v_error_message:= 'Insert Products: One of selects returned nothing';
Insert Into errors Values (v_error_code,v_error_message, systimestamp);
RETURN v_result;
When others Then
ROLLBACK;
v_error_code := SQLCODE;
v_error_message:=substr(SQLERRM,1,50);
Insert Into errors Values (v_error_code,'Error inserting products list',systimestamp);
RETURN v_result;
END;
Me gustaría personalizar más de mis excepciones o hacer un bloque de excepción para cada selección / inserción. ¿Es eso posible o correcto?
Si es así, podría por favor, muéstrame algo de código con excepciones importantes que se arrojaron por esta función?
Solución
-
En la sección de excepción; puede aumentar el error de aplicación o devolver 0 con la explicación código de error. Se trata de su elección.
-
Si desea registrar sus errores en la sección de excepción (o en la sección principal), escriba su propio procedimiento de registro con la transacción autónoma. así, su mecanismo de registro no se ve afectada por la de su principal operación COMMIT o ROLLBACK. (Ver: http://www.dba-oracle.com/t_autonomous_transaction.htm )
cláusula -
Otro mecanismo de registro (DML Error Log) en Oracle 10gR2 (y superior) son los errores de registro (ver: http://www.oracle-base.com/articles/10g/DmlErrorLogging_10gR2.php ).
Otros consejos
Si lo que desea es sustituir su propio mensaje de error, no es RAISE_APPLICATION_ERROR
...
When no_data_found then
RAISE_APPLICATION_ERROR(-20000
, 'Insert Products: One of selects returned nothing';
, true);
El tercer parámetro devuelve el error original, así como su ser personalizado.
Oracle también nos da la opción de definir nuestras excepciones. Esto puede ser útil si queremos pasar la excepción de un programa llamando ...
Declare
no_product_found exception;
Begin
....
When no_data_found then
raise no_product_found;
Esto sería más eficaz si definimos la excepción NO_PRODUCT_FOUND en una especificación del paquete en el que podría ser referenciado por unidades de programas externos.
Además, Oracle proporciona el pragma INIT_EXCEPTION que nos permite asociar los números de error de Oracle con nuestros excepciones personalizadas. Desafortunadamente, no podemos sobrecargar los números de error, que Oracle ya ha definidas (por ejemplo, no podemos crear nuestras propias excepciones para ORA-1403 que ya está cubierto por la excepción NO_DATA_FOUND). obtener más información.