Как создать два триггера, которые запускают друг друга и ограничить их запуск двумя разами?

Как создать два триггера, которые запускают друг друга и ограничить их запуск двумя разами?

Понимаю, как триггеры могут запускать друг друга. Например, есть на двух таблицах по триггеру реагирующих на insert, и когда один из них срабатывает он добавляет запись в другую таблицу, тем самым активирует второй триггер, который добавляет строку в первую таблицу и т.д.

Но не понимаю, как можно ограничить их запуск двумя разами. Помогите, пожалуйста.


Ответы (2 шт):

Автор решения: 0xdb

Создайте переменные сессии, вот так:

create or replace package trigcontrol as
    type callcounters is record (t1 int := 0, t2 int := 0);
    calls callcounters; 
end;

И ведите в них подсчёт рекурсивных вызовов. Пример реализации триггера:

create or replace trigger t1trig before insert on t1 for each row 
begin
    if trigcontrol.calls.t1 = 2 then
        raise_application_error (-20000, 'trigcontrol.calls.t1==2');
    end if;
    trigcontrol.calls.t1 := trigcontrol.calls.t1+1;
    insert into t2 values (:new.col);
    trigcontrol.calls.t1 := 0;
exception when others then
    trigcontrol.calls.t1 := 0;
    raise;
end;

PS Это не решение для реального проекта, только для демонстрации в процессе обучения.

→ Ссылка
Автор решения: default locale

Примитивное решение: добавить в каждую таблицу поле-флаг (например, FROM_TRIGGER number(1) default 0), которое будет определять проставлено ли значение из другого триггера или нет.

Соответственно, в триггерах проверять флаг и добавлять записи в зависимости от него. Так можно контролировать в каких случаях добавляется новая строка, а в каких нет.

CREATE OR REPLACE TRIGGER t1_before_insert
BEFORE INSERT
   ON t1
   FOR EACH ROW

BEGIN

   IF :new.from_trigger = 0 THEN
      --Добавляем запись
      INSERT INTO t2(..., from_trigger)
      VALUES(..., 1);
   END IF

END;

Аналогично для второй таблицы. Если нужна более сложная логика, то можно назвать поле TRIGGER_ACTION и использовать для него больше разных значений.

→ Ссылка