Обработка ошибок Oracle

У меня есть такой код:

DECLARE
  e_not_exist EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_not_exist, -942);
  car_name VARCHAR2(20);
BEGIN
  select name_of_factory into car_name from car where car_id = 1;
  dbms_output.put_line(car_name);
EXCEPTION
  when e_not_exist then
    dbms_output.put_line('Table or view does not exist');
  when OTHERS then
    dbms_output.put_line(to_char(SQLCODE));
END;

На самом деле, моя таблица называется CARS, а не CAR. Но оракул не обрабатывает это исключение и выдает ошибку ORA-00942: Таблица или представление не существует. Как я могу обработать это исключение?


person maks    schedule 17.11.2010    source источник


Ответы (2)


Вы не можете сделать это со статическим SQL. Ошибка возникает, когда код компилируется, а не выполняется. Попробуйте это вместо этого:

 execute immediate 'select name_of_factory from car where car_id = 1' 
                    into car_name ;
person Dan    schedule 17.11.2010
comment
благодаря. Насколько я понимаю, есть ошибки компиляции и выполнения. Как определить ошибку времени выполнения или компиляции, если я знаю номер ошибки? - person maks; 17.11.2010
comment
Это не основано на количестве. Как вы можете видеть из этого самого примера, одна и та же ошибка (-942) может быть либо во время выполнения, либо во время компиляции в зависимости от обстоятельств. Проблема в том, что когда вы используете DECLARE/BEGIN inline, трудно заметить разницу. Один из вариантов — создать процедуру, а затем выполнить ее. Другой способ - сделать то, что у вас есть здесь - поскольку вы используете WHEN OTHERS, все исключения времени выполнения будут перехвачены таким образом, поэтому любые всплывающие ошибки будут возникать во время компиляции. - person Dan; 17.11.2010

Ошибка ORA-00942 обычно является ошибкой времени компиляции. Oracle должен разрешать имена таблиц во время компиляции. Обработчики исключений будут перехватывать ошибки во время выполнения, а не во время компиляции.

Если вы использовали динамический SQL, вы можете отложить разрешение имен до времени выполнения, после чего вы сможете перехватить исключение, т.е.

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    no_such_table exception;
  3    pragma exception_init( no_such_table, -942 );
  4    l_cnt integer;
  5  begin
  6    execute immediate 'select count(*) from emps' into l_cnt;
  7  exception
  8    when no_such_table
  9    then
 10      dbms_output.put_line( 'No such table' );
 11* end;
SQL> /
No such table

PL/SQL procedure successfully completed.

Но в общем случае это неразумный способ написания хранимых процедур. Ваши процедуры должны знать, какие таблицы существуют на самом деле, а синтаксические ошибки следует выявлять и устранять во время разработки, а не во время выполнения.

person Justin Cave    schedule 17.11.2010