質問

頻繁に、1 つまたは複数のテーブルで挿入/削除/更新する関数を実行していることに気づきましたが、次のような予期された例外が処理されていることがわかりました。 no_data_found, dupl_val_on_index, 、など。このような挿入の場合:

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;

例外をさらにカスタマイズするか、選択/挿入ごとに例外ブロックを実行したいと考えています。それは可能ですか、それとも正しいですか?

もしそうなら、この関数によってスローされる重要な例外を含むコードをいくつか見せていただけますか?

役に立ちましたか?

解決

  • 例外セクション:アプリケーション エラーを発生させるか、エラー コードの説明とともに 0 を返すことができます。それはあなたの選択にかかっています。

  • エラーを例外セクション (またはメイン セクション) に記録したい場合は、AUTONOMOUS TRANSACTION を使用して独自のログ プロシージャを作成します。したがって、ロギング メカニズムはメイン トランザクションの COMMIT または ROLLBACK の影響を受けません。(見る: http://www.dba-oracle.com/t_autonomous_transaction.htm)

  • Oracle 10gR2 (以降) の別のロギング メカニズム (DML エラー ログ) は、LOG ERRORS 句です (以下を参照)。 http://www.oracle-base.com/articles/10g/DmlErrorLogging_10gR2.php).

他のヒント

あなただけの独自のエラーメッセージを代用したい場合は、

RAISE_APPLICATION_ERROR ...

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

3番目のパラメータは、元のエラーだけでなく、あなたのカスタム1を返します。

Oracleはまた、私たちの例外を定義するためのオプションを提供します。我々は呼び出し元のプログラムに例外を渡したい場合に便利です...

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

私たちは、それが外部のプログラム単位で参照することができ、パッケージ仕様でNO_PRODUCT_FOUND例外を定義した場合、これは最も効果的であろう。

また、オラクルは、私たちは私たちのカスタム例外をOracleエラー番号を関連付けることができますINIT_EXCEPTIONプラグマを提供します。残念ながら、私たちは、(例えば、我々はすでにNO_DATA_FOUND例外で覆われているORA-1403のための当社独自の例外を作成することはできません)Oracleは、すでに定義されたエラー番号をオーバーロードすることはできません。 詳細をご覧ください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top