обрабатывать исключение pl / sql: получать значение там, где произошло исключение

#oracle #plsql

#Oracle #plsql

Вопрос:

Я использую этот код

 BEGIN
EXECUTE IMMEDIATE 'INSERT INTO MY_TABLE (A, B , C)
                  SELECT TABLE_2.A, TABLE_2.B, TABLE_2.C
                  FROM TABLE_2
                  WHERE TABLE_2.A in (val1,val2,val3) ';

EXCEPTION WHEN OTHERS then 
                PROC_EXCEPTION('ERROR',TABLE_2.B,SQLCODE,SQLERRM);
END;
 

И я получаю следующую ошибку компиляции:

TABLE_2.B must be declared

как я могу получить значение TABLE_2.B того, где произошло исключение, и передать его процедуре, обрабатывающей исключение?

Комментарии:

1. Вы не можете. Исключение обрабатывается для всего оператора , а не для строки, которая завершается ошибкой.

Ответ №1:

Вам нужно использовать предложение LOG ERRORS INTO https://oracle-base.com/articles/10g/dml-error-logging-10gr2

Для создания таблицы журнала ошибок, пожалуйста, используйте https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_errlog.htm#CEGBBABI

Затем после завершения вставки вы можете обрабатывать записи из таблицы ошибок.

Комментарии:

1. Это не приведет к обнаружению синтаксических ошибок, как показано в вопросе

2. @a_horse_with_no_name да, это улавливает только некоторые исключения в значении, а не в синтаксисе, но вопрос был: как я могу получить значение, в котором произошла ошибка? Итак, я понимаю, что речь идет о вставленном значении.

Ответ №2:

Вы не можете ссылаться TABLE.A за пределы EXECUTE IMMEDIATE блока…

Попробуйте:

 BEGIN
EXECUTE IMMEDIATE 'INSERT INTO MY_TABLE (A, B , C)
              SELECT TABLE_2.A, TABLE_2.B, TABLE_2.C
              FROM TABLE_2
              WHERE TABLE_2.A in (val1,val2,val3) ';

EXCEPTION WHEN OTHERS then 
            PROC_EXCEPTION('ERROR with TABLE_2.B',SQLCODE,SQLERRM);
END;
 

Чтобы иметь значение для TABLE_2.B , сделайте это в цикле:

 BEGIN
  for x in (SELECT TABLE_2.A, TABLE_2.B, TABLE_2.C
              FROM TABLE_2
              WHERE TABLE_2.A in (val1,val2,val3))
  loop
    begin
      execute immediate 'INSERT INTO MY_TABLE (A, B , C) values ('||x.A||','||x.B||','||x.C||')';
        EXCEPTION WHEN OTHERS then 
           PROC_EXCEPTION('ERROR with'|| x.B,SQLCODE,SQLERRM);
    end;
  end loop;

END;
 

Комментарии:

1. спасибо за ответ .. но что, если у меня действительно был случай, когда тогда в моем операторе выбора, как я могу использовать значения вставки?