Personalizza eccezioni PL / SQL in Oracle
-
21-09-2019 - |
Domanda
Spesso mi sono ritrovata a fare alcune funzioni per inserire / cancellare / aggiornamento in una o più tabelle e ho visto alcune eccezioni previste stati presi cura di, come no_data_found
, dupl_val_on_index
, ecc Per un inserto in questo modo:
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;
Vorrei personalizzare più delle mie eccezioni o di fare un blocco di eccezioni per ogni select / insert. È quello possibile o corretto?
Se è così, potrebbe per favore mi mostrare un po 'di codice con importanti eccezioni di essere gettarono da questa funzione?
Soluzione
-
Nella sezione un'eccezione; è possibile aumentare errore di applicazione o restituire 0 con codice di errore spiegazione. Si tratta di circa la vostra scelta.
-
Se si desidera accedere i vostri errori nella sezione di eccezione (o nella sezione principale), scrivere il proprio procedura di registrazione con la transazione autonomo. così, il vostro meccanismo di registrazione non è influenzato dal del vostro transazione principale commit o rollback. (Vedi: http://www.dba-oracle.com/t_autonomous_transaction.htm )
Clausola -
Un altro meccanismo di registrazione (DML Error Log) in Oracle 10gR2 (e sopra) è errori nel registro (vedi: http://www.oracle-base.com/articles/10g/DmlErrorLogging_10gR2.php ).
Altri suggerimenti
Se si desidera solo per sostituire il proprio messaggio di errore, c'è RAISE_APPLICATION_ERROR
...
When no_data_found then
RAISE_APPLICATION_ERROR(-20000
, 'Insert Products: One of selects returned nothing';
, true);
Il terzo parametro restituisce l'errore originale così come il vostro uno personalizzato.
Oracle ci dà anche la possibilità di definire le nostre eccezioni. Questo può essere utile se si vuole passare l'eccezione di un programma chiamando ...
Declare
no_product_found exception;
Begin
....
When no_data_found then
raise no_product_found;
Questo sarebbe più efficace se abbiamo definito l'eccezione NO_PRODUCT_FOUND in una specifica pacchetto di dove potrebbe essere referenziato da unità programma esterno.
Inoltre, Oracle fornisce il pragma INIT_EXCEPTION che ci permette di associare numeri di errore Oracle con le nostre eccezioni personalizzate. Purtroppo non possiamo sovraccaricare numeri di errore che Oracle ha già definito (per esempio, non siamo in grado di creare le nostre eccezioni per ORA-1403 che è già coperto dalla deroga NO_DATA_FOUND). saperne di più.