При реализации триггера уровня оператора в таблице возможно ли получить записи OLD и NEW для всех затронутых строк? - PullRequest
13 голосов
/ 06 мая 2011

В Oracle вы можете написать триггер уровня строки, указав предложение FOR EACH ROW в операторе CREATE TRIGGER:

CREATE TRIGGER MY_FANCY_TRIGGER
  BEFORE UPDATE ON MY_TABLE
  FOR EACH ROW
BEGIN
  IF :OLD.my_id_column > 4 AND :NEW.some_other_column <> 'foo' THEN
    -- ...
  END IF;
END;

Такой триггер позволяет просматривать до и после версий каждой затронутой строки (:OLD и :NEW соответственно). Например, следующий оператор вызовет выполнение этого триггера один раз для каждой строки в MY_TABLE:

UPDATE MY_TABLE SET some_other_column = 'bar';

Удаляя предложение FOR EACH ROW, триггер становится триггером уровня . Это означает, что он выполняется только один раз для оператора , независимо от того, сколько строк (если таковые имеются) были затронуты оператором. К сожалению, триггеры на уровне операторов не имеют доступных переменных :OLD и :NEW (поскольку количество затронутых строк различается).

Можно ли получить значения :OLD и :NEW для всех затронутых строк внутри триггера уровня оператора? У меня есть некоторая обработка, которую я предпочел бы выполнять только один раз для каждого оператора.

Ответы [ 2 ]

10 голосов
/ 06 мая 2011

Один из подходов, предложенных Джастином Кейвом, - хранить информацию в триггерах уровня строк в отдельных коллекциях пакетов.

Если вы используете 11g, то правильным подходом будет использование составных триггеров. Это позволяет избежать создания отдельного пакета для хранения ключей - это можно сделать в самом триггере,

8 голосов
/ 06 мая 2011

Не напрямую, нет.

Стандартный подход - это «триггерное решение» (чаще используется, когда вы пытаетесь обойти проблему с изменяющейся таблицей)

  1. Создайте пакет, содержащий набор ключей для вашей таблицы
  2. Создать триггер оператора before, который инициализирует коллекцию
  3. Создание триггера уровня строки, который вставляет ключи в коллекцию.
  4. Создать триггер оператора после, который использует ключи в коллекции для своей обработки

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

Как указывает josephj1989 ниже, если вы используете 11g, вы можете использовать составные триггеры , чтобы немного упростить это. Вы по-прежнему будете объявлять коллекцию, заполнять коллекцию в теле триггера уровня строки и обрабатывать коллекцию в триггере уровня оператора. Но будет только один объект для создания и управления, а не несколько объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...