Настройка исключений PL / SQL в Oracle - PullRequest
1 голос
/ 16 января 2010

Часто я обнаруживал, что выполняю некоторые функции для вставки / удаления / обновления в одной или нескольких таблицах, и я видел, что некоторые ожидаемые исключения были обработаны, например 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;

Я хотел бы настроить больше моих исключений или сделать блок исключений для каждого выбора / вставки. Это возможно или правильно?

Если это так, не могли бы вы показать мне код с важными исключениями, выдаваемыми этой функцией?

Ответы [ 2 ]

4 голосов
/ 17 января 2010

Если вы просто хотите заменить свое сообщение об ошибке, есть 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). Узнайте больше.

1 голос
/ 17 января 2010
  • В разделе исключений; Вы можете вызвать ошибку приложения или вернуть 0 с объяснением кода ошибки. Это о вашем выборе.

  • Если вы хотите регистрировать свои ошибки в разделе исключений (или в основном разделе), напишите свою собственную процедуру регистрации с помощью АВТОНОМНОЙ СДЕЛКИ. Таким образом, на механизм ведения журнала не влияет COMMIT или ROLLBACK вашей основной транзакции. (см .: http://www.dba -oracle.com / t_autilitary_transaction.htm )

  • Другим механизмом ведения журнала (журнал ошибок DML) в Oracle 10gR2 (и выше) является предложение LOG ERRORS (см .: http://www.oracle -base.com / Articles / 10g / DmlErrorLogging_10gR2.php ) .

...