Обработка ошибки ORA-00942 при insert, update, delete

На днях возникла простенькая, но нестандартная задачка. Как грамотно отловить ошибку ORA-00942 “Таблица или представление не существует” в обычном PL/SQL блоке при попытке выполнения любой команды DML? Ну есть 2 класса пользователей, одни имеют разрешение на изменение таблицы, другие – нет. Но, т.к. весь блок состоит из нескольких операций, не хотелось создавать копии, отличающиеся одной командой, а разобраться на месте в самом блоке. Ошибка возникает на стадии лексического разбора, поэтому до обработки исключений дело не доходит. Решить такую задачу помогает динамический SQL.

declare
    < необходимые объявления>
begin
    < различные операции>
    -- начало вложенного блока обработки выполнения DML
    declare
        -- создаем и открываем курсор
        cr int := dbms_sql.open_cursor;
        v_rows int;
        -- тот самый запрос, который может вызвать ошибку из-за отсутствия видимости (допустим, удалить запись с заданным идентификатором)
        v_sql varchar2(32767) := 'delete from my_table where ID = :p_id';
    begin
        -- лексический разбор заданной команды
        dbms_sql.parse(cr, v_sql, dbms_sql.native);
        -- если в запросе есть связанные переменные, присваиваем им значения (в нашем примере переменная p_id)
        DBMS_SQL.BIND_VARIABLE(cf, ':p_id', 100);
        -- выполнение запроса
        v_rows := DBMS_SQL.EXECUTE(cf);
        -- не забываем закрыть курсор
        dbms_sql.close_cursor (cf);
        -- обработка ошибки
    exception when OTHERS then
        -- после отлавливания любой ошибки проверяем ее код, если это ожидаемая
        -- нами ORA-00942, ничего не делаем или, наоборот, выполняем какие-то обработчики,
        -- в случае любой другой ошибки вызываем ее заново
        if SQLCODE = -942 then
            null;
        else
            raise;
        end if;
    end;
end;

 

Close Menu