Question

Souvent je me suis retrouvé à faire certaines fonctions pour insérer / supprimer / mettre à jour dans une ou plusieurs tables et je l'ai vu quelques exceptions prévues été pris en charge, comme no_data_found, dupl_val_on_index, etc. Pour un insert comme ceci:

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;

Je voudrais personnaliser plus de mes exceptions ou faire un bloc d'exception pour chaque sélection / insert. Est-ce possible ou pas?

Si oui, pourriez s'il vous plaît me montrer un peu de code avec des exceptions importantes étant par cette fonction jetèrent?

Était-ce utile?

La solution

  • Dans la section d'exception; vous pouvez augmenter erreur d'application ou retourner 0 avec le code d'erreur explication. Il est de votre choix.

  • Si vous voulez enregistrer vos erreurs dans la section d'exception (ou dans la section principale), écrivez votre propre procédure d'enregistrement avec TRANSACTION AUTONOME. donc, votre mécanisme de journalisation n'est pas affecté par ou ROLLBACK de COMMIT votre transaction principale. (Voir: http://www.dba-oracle.com/t_autonomous_transaction.htm )

  • est erreurs de journal clause Un autre mécanisme de journalisation (DML Error Log) dans Oracle 10gR2 (et au-dessus) (voir: http://www.oracle-base.com/articles/10g/DmlErrorLogging_10gR2.php ).

Autres conseils

Si vous voulez juste de remplacer votre propre message d'erreur, il est RAISE_APPLICATION_ERROR ...

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

Le troisième paramètre renvoie l'erreur d'origine ainsi que votre une sur mesure.

Oracle nous donne aussi la possibilité de définir nos exceptions. Cela peut être utile si nous voulons passer l'exception à un programme appelant ...

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

Ce serait plus efficace si nous avons défini l'exception NO_PRODUCT_FOUND dans une spécification de package où il pourrait être référencé par des unités de programmes externes.

En outre, Oracle fournit la pragma INIT_EXCEPTION qui nous permet d'associer les numéros d'erreur Oracle avec nos exceptions personnalisées. Malheureusement, nous ne pouvons pas surcharger les numéros d'erreur qui Oracle a déjà défini (par exemple, nous ne pouvons pas créer nos propres exceptions pour ORA-1403 qui est déjà couvert par l'exception NO_DATA_FOUND). En savoir plus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top