2010-01-16 33 views
1

通常我發現自己在一個或多個表中執行了一些插入/刪除/更新的功能,並且我已經看到一些預期的例外已被處理,如no_data_found,dupl_val_on_index等。像這樣插入:自定義Oracle中的PL/SQL例外

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; 

我想定製更多的異常或爲每個select/insert做一個異常塊。這是可能的還是正確的?

如果是這樣,請給我看一些代碼,重要的例外是被這個函數拋出?

回答

1
4

如果你只是想替換自己的錯誤消息,有RAISE_APPLICATION_ERROR ...

When no_data_found then 
    RAISE_APPLICATION_ERROR(-20000 
          , 'Insert Products: One of selects returned nothing'; 
          , true); 

第三個參數返回原來的錯誤,以及您的自定義一個。

Oracle還爲我們提供了定義異常的選項。如果我們想將異常傳遞到調用程序這是很有用...

Declare 
    no_product_found exception; 
Begin 
    .... 
When no_data_found then 
    raise no_product_found; 

如果我們在那裏可以通過外部程序單位引用的包裝規範中定義的NO_PRODUCT_FOUND例外,這將是最有效的。

另外,Oracle提供了INIT_EXCEPTION編譯指示,它允許我們將Oracle錯誤編號與我們的自定義異常相關聯。不幸的是,我們不能重載Oracle已經定義的錯誤數字(例如,我們不能爲ORA-1403創建自己的例外,這已經被NO_DATA_FOUND例外所涵蓋)。 Find out more.