Использование OLD. контекстных переменных в INSERT триггерах
Добавлено: 03 дек 2005, 11:48
Возникли вопросы по использованию OLD. контекстных переменных в INSERT триггерах.
Конечно в чистых триггерах на вставку OLD-переменные просто не нужны. Я говорю о универсальных триггерах
(on INSERT or UPDATE к примеру), вызываемых при вставке записи.
Пример:
Теперь встявляем в таблицу запись:
Всё ОК, ошибок нет, т.е. вроде как можем использовать OLD-переменные в инсерт/апдейт триггерах напрямую, без ветвлений типа:
теперь дабавим еще метаданных:
и выполним процедуру:
в ответ ошибка:
далее отключаем ранее созданный триггер и пробуем еще раз выполнить процедуру:
Т.е.ошибка -508 no current record for fetch operation вылазит из-за использования OLD.ID при выполнении инсерта.
Почему так?
Если просто вставляем запись, то всё ОК, а если после инсерта вызвать какое-то исключение,
то вылазит не это исключение, а ошибка, связанная с использованием OLD.ID.
Какая-то неоднозначность. Мне кажется, либо ошибка SQLCODE = -508 должна возникать всегда,
когда идет обращение к контексту OLD. в INSERT триггере, либо не должна возникать вообще,
что означало бы, что в INSERT триггере любая OLD.переменная is NULL.
Второй вариант кажется логичным, потому что позволяет использовать универсатьные триггеры действительно универсально,
без усложнения их логики. Сейчас вроде так и работает, но как-то не до конца...
Разьясните ситуацию.
Сервер: LI-V1.5.3.4854 Firebird 1.5
Конечно в чистых триггерах на вставку OLD-переменные просто не нужны. Я говорю о универсальных триггерах
(on INSERT or UPDATE к примеру), вызываемых при вставке записи.
Пример:
Код: Выделить всё
CREATE TABLE TAB (
ID INTEGER
);
SET TERM ^ ;
CREATE TRIGGER TAB_BIU0 FOR TAB
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
begin
if (old.ID=2) then new.ID=2;
end
^
Код: Выделить всё
insert into Tab values(1);
Код: Выделить всё
if (inserting) ....
if (updating)
Код: Выделить всё
CREATE EXCEPTION ERR 'My Error!';
SET TERM ^ ;
CREATE PROCEDURE PROC
AS
begin
insert into Tab values(1);
exception Err;
end^
Код: Выделить всё
execute procedure Proc;
Код: Выделить всё
Statement failed, SQLCODE = -508
no current record for fetch operation
-exception 1
-My Error!
Код: Выделить всё
Statement failed, SQLCODE = -836
exception 1
-My Error!
Почему так?
Если просто вставляем запись, то всё ОК, а если после инсерта вызвать какое-то исключение,
то вылазит не это исключение, а ошибка, связанная с использованием OLD.ID.
Какая-то неоднозначность. Мне кажется, либо ошибка SQLCODE = -508 должна возникать всегда,
когда идет обращение к контексту OLD. в INSERT триггере, либо не должна возникать вообще,
что означало бы, что в INSERT триггере любая OLD.переменная is NULL.
Второй вариант кажется логичным, потому что позволяет использовать универсатьные триггеры действительно универсально,
без усложнения их логики. Сейчас вроде так и работает, но как-то не до конца...
Разьясните ситуацию.
Сервер: LI-V1.5.3.4854 Firebird 1.5