Обработка исключений ORACLE

Мне нужно обработать ошибку ORA-01400 (невозможно вставить NULL в ("SCHEMA "."TABLE_NAME"."COLUMN_NAME") ) с использованием дескриптора исключения.

ORACLE предопределяет несколько исключений, таких как (ACCESS_INTO_NULL, ZERO_DIVIDE и т. д.), но, по-видимому, не определяет исключение для ошибки ORA-01400, как мне обрабатывать этот конкретный код ошибки?

Мне нужно что-то вроде этого (другие предложения принимаются).

....
 ...     
 INSERT INTO MY_TABLE (CODE, NAME) VALUES (aCode,aName);
 COMMIT;
   EXCEPTION
     WHEN NULL_VALUES THEN /* i don't know this value , exist?*/
       Do_MyStuff();
     WHEN OTHERS THEN
       raise_application_error(SQLCODE,MY_OWN_FORMAT_EXCEPTION(SQLCODE,SQLERRM),TRUE); 
    END;

person RRUZ    schedule 29.12.2009    source источник


Ответы (4)


Предопределенные исключения PL/SQL являются специальными для Oracle. Вы действительно не можете связываться с теми. Если вы хотите иметь собственный набор предопределенных исключений, вы не можете объявить их «глобально», как стандартные. Вместо этого создайте пакет exceptions, содержащий все объявления исключений, и используйте его в своем коде приложения.

Пример:

CREATE OR REPLACE PACKAGE my_exceptions
AS
  insert_null_into_notnull EXCEPTION;
  PRAGMA EXCEPTION_INIT(insert_null_into_notnull, -1400);

  update_null_to_notnull EXCEPTION;
  PRAGMA EXCEPTION_INIT(update_null_to_notnull, -1407);
END my_exceptions;
/

Теперь используйте исключение, определенное в пакете

CREATE OR REPLACE PROCEDURE use_an_exception AS
BEGIN
  -- application specific code ...
  NULL;
EXCEPTION
  WHEN my_exceptions.insert_null_into_notnull THEN
     -- application specific handling for ORA-01400: cannot insert NULL into (%s)
     RAISE;
END;
/

Источник: http://www.orafaq.com/wiki/Exception

person Adam Hawkes    schedule 29.12.2009

Вы можете обрабатывать исключение по его коду следующим образом:

....
 ...
 INSERT INTO MY_TABLE (CODE, NAME) VALUES (aCode,aName);   
 COMMIT;   
   EXCEPTION   
     WHEN OTHERS THEN   
       IF SQLCODE = -1400 THEN
         Do_MyStuff();
       ELSE
         raise_application_error(SQLCODE,MY_OWN_FORMAT_EXCEPTION(SQLCODE,SQLERRM),TRUE);
       END IF;
    END;   
person Egor Rogov    schedule 29.12.2009

вы можете определить свои собственные исключения, такие как переменные (они будут иметь ту же область действия, что и другие переменные, поэтому вы можете определить исключение пакета и т. д.):

SQL> DECLARE
  2     NULL_VALUES EXCEPTION;
  3     PRAGMA EXCEPTION_INIT(NULL_VALUES, -1400);
  4  BEGIN
  5     INSERT INTO t VALUES (NULL);
  6  EXCEPTION
  7     WHEN null_values THEN
  8        dbms_output.put_line('null value not authorized');
  9  END;
 10  /

null value not authorized

PL/SQL procedure successfully completed
person Vincent Malgrat    schedule 29.12.2009
comment
Винсент, это я уже знал, проблема этого решения в том, что мне нужно определить исключение для каждой конкретной таблицы. Я ищу способ обслуживать любую таблицу в моей схеме. - person RRUZ; 29.12.2009
comment
создайте триггер на уровне схемы для обработки этого пользовательского исключения - person afftee; 29.12.2009
comment
@RRUZ: я действительно не понимаю, вы можете использовать это исключение с ЛЮБОЙ таблицей. Если вы определите его в заголовке пакета, вы сможете использовать его везде (то есть: это будет точно как предопределенное исключение оракула) - person Vincent Malgrat; 29.12.2009
comment
Я думаю, что недостающая часть - это изучить SQLERRM, чтобы найти таблицу/столбец, вызывающий исключение. - person Adam Hawkes; 29.12.2009
comment
@ Адам, меня не интересует таблица / столбец, вызывающий исключение, просто мне нужно обработать это конкретное исключение, как ORACLE, с предопределенными исключениями. - person RRUZ; 29.12.2009
comment
Хорошо... Думаю, я понял. Вы не хотите объявлять исключение в каждом блоке PL/SQL... вы хотите объявить его один раз и сделать его известным для всей системы? - person Adam Hawkes; 29.12.2009
comment
Да @Адам, что-то в этом роде. - person RRUZ; 29.12.2009

 INSERT INTO MY_TABLE (CODE, NAME) VALUES (aCode,aName);
 COMMIT;  

      EXCEPTION
         WHEN NULL_VALUES /* i don't know this value , exist?*/
           emesg := SQLERRM;
           dbms_output.put_line(emesg); 
         WHEN OTHERS THEN
           emesg := SQLERRM;
           dbms_output.put_line(emesg);
         END;

SQLERRM показывает сообщение об ошибке sql

http://www.psoug.org/reference/exception_handling.html

person Gerard Banasig    schedule 29.12.2009