Anpassen PL / SQL-Ausnahmen in Oracle
-
21-09-2019 - |
Frage
Häufig fand ich mich einige Funktionen tun einfügen / löschen / update in einer oder mehreren Tabellen, und ich habe einige erwartete Ausnahmen darauf geachtet worden, gesehen wie no_data_found
, dupl_val_on_index
, etc. Für einen Einsatz wie folgt aus:
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;
Ich möchte mehr meine Ausnahmen anpassen oder für jeden select / Einsatz einen Ausnahmeblock tun. Ist das möglich oder richtig?
Wenn ja, bitte mir einige Codes mit wichtigen Ausnahmen zeigen konnte durch diese Funktion throwed werden?
Lösung
-
Im Ausnahmeabschnitt; Sie können Anwendungsfehler oder 0 zurück mit dem Fehlercode Erklärung erhöhen. Es geht um Ihre Wahl.
-
Wenn Sie Ihre Fehler in der Ausnahme Abschnitt einzuloggen (oder in Hauptteil), schreiben Sie Ihre eigene Protokollieren mit AUTONOMOUS TRANSACTION. COMMIT oder ROLLBACK so wird Ihr Logging-Mechanismus nicht von Ihrem Haupt Transaktion betroffen. (Siehe: http://www.dba-oracle.com/t_autonomous_transaction.htm )
-
Ein weiterer Logging-Mechanismus (DML Error Log) in Oracle 10gR2 (und höher) ist Protokollfehler-Klausel (siehe: http://www.oracle-base.com/articles/10g/DmlErrorLogging_10gR2.php ).
Andere Tipps
Wenn Sie gerade Ihre eigene Fehlermeldung ersetzen wollen, gibt es RAISE_APPLICATION_ERROR
...
When no_data_found then
RAISE_APPLICATION_ERROR(-20000
, 'Insert Products: One of selects returned nothing';
, true);
Der dritte Parameter gibt die ursprünglichen Fehler sowie Ihre individuellen ein.
Oracle gibt uns auch die Möglichkeit, unsere Ausnahmen zu definieren. Dies kann nützlich sein, wenn wir die Ausnahme von einem Aufrufer übergeben wollen ...
Declare
no_product_found exception;
Begin
....
When no_data_found then
raise no_product_found;
Dies wäre am effektivsten, wenn wir die NO_PRODUCT_FOUND Ausnahme in einer Paket-Spezifikation definiert, wo es durch externe Programmeinheiten verwiesen werden.
Darüber hinaus bietet Oracle die INIT_EXCEPTION Pragma, die uns Oracle Fehlernummern mit unseren kundenspezifischen Ausnahmen assoziieren können. Leider können wir keine Fehlernummern überlasten, die Oracle bereits definiert haben (zum Beispiel, können wir nicht unsere eigenen Ausnahmen für ORA-1403 schaffen, die bereits von der NO_DATA_FOUND Ausnahme bedeckt ist). Mehr aus.