Oracle: исключая обновления одного столбца для запуска триггера - PullRequest
10 голосов
/ 14 сентября 2009

В оракуле я могу указать столбцы, которые должны вызывать срабатывание триггера:

create or replace trigger my_trigger
before update of col1, col2, col3 on my_table for each row
begin
  // the trigger code will be executed only if col1 or col2 or col3 was updated
end;

Теперь я хочу сделать следующее: я не хочу, чтобы сработал триггер, когда обновлен только один столбец . Как это возможно?

Я мог бы перечислить все столбцы, кроме одного, который не должен вызывать срабатывание триггера. Это довольно громоздко для таблиц с большим количеством столбцов.

Другим способом было бы использовать функцию ОБНОВЛЕНИЯ следующим образом:

if not updating('COL3') then ...

Но если я изменил COL1 и COL3 сразу, утверждение оценивается как ложное. Это не то, что я хочу, так как я хочу ограничить выполнение, когда был обновлен только один столбец (COL3).

Ответы [ 4 ]

11 голосов
/ 14 сентября 2009

Вы можете сделать что-то вроде этого:

create or replace trigger my_trigger
before update on my_table
for each row
declare
   n_cols integer := 0;
begin
   for r in (select column_name from all_tab_columns
             where table_name = 'MY_TABLE'
             and owner = 'MY_SCHEMA')
   loop
      if updating(r.column_name) then
         n_cols := n_cols + 1;
         exit when n_cols > 1;
      end if;
   end loop;
   if n_cols > 1 then
      do_something;
   end if;
end;

Вероятно, не очень эффективно, хотя!

5 голосов
/ 20 января 2011

У меня вчера была такая же проблема. Я хотел закодировать триггер, который срабатывал на каждом поле, кроме одного, в таблице было 103 столбца.

Первый код:

if (:OLD.col1<>:NEW.col1 or :OLD.col2<>:NEW.col2 or :OLD.col3<>:NEW.col3 ....)

Но у меня были некоторые проблемы с нулевыми значениями, поэтому я добавил:

if (NVL(:OLD.col1,0)<>NVL(:NEW.col1,0) or NVL(:OLD.col2,0)<>NVL(:NEW.col2,0)  ....)

Но потом у меня возникли проблемы со столбцами DATE, это стало беспорядком ..

Я думаю, что лучшее решение - перечислить все столбцы, которые вы хотите проверить, в «OF»:

AFTER INSERT OR UPDATE of cOL1, col2, col3 ... colN ON table1

Это не было "элегантно", но ... оно работало идеально.

3 голосов
/ 28 сентября 2009

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

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

0 голосов
/ 14 сентября 2009

Я не думаю, что есть способ избежать перечисления всех других столбцов в таблице, либо в теле триггера, либо в предложении before update of ....

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

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