триггеры в новых и старых столбцах - PullRequest
0 голосов
/ 07 декабря 2009

Почему мы не можем использовать: новые и: старые столбцы в триггере уровня оператора?

Ответы [ 3 ]

6 голосов
/ 07 декабря 2009

Поскольку это может быть случай, когда оператор вставляет / удаляет / обновляет более одной строки. Таким образом, столбец new или old не существует.

Пример:

update FOO set a = 12 where b = 9;

Или:

delete from FOO where b = 9;

Или:

insert into FOO (a, b) select 12, x from BAR;

Если в таблице FOO имеется триггер оператора, в этих трех предложениях нет способа определить, работаете ли вы с одной, несколькими или несколькими строками.

4 голосов
/ 07 декабря 2009

Поскольку DML мог быть основан на множестве, влияя на несколько строк в таблице. На самом деле, поскольку SQL правильно настроен, это должно быть обычным случаем. Следовательно, триггеры уровня оператора не могут определить, какие значения: OLD и какие: NEW вы имеете в виду.

0 голосов
/ 23 декабря 2009

Как уже было сказано выше, триггеры уровня оператора могут быть от одного до нескольких изменений строки, поэтому: new и: old недоступны.

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

Пакет:

create or replace package table_trigger_helper is

  subtype subtype_rowtype is table_name$rowtype;
  type table_rowtype is table of subtype_rowtype;

  v_old table_rowtype := table_rowtype();
  v_new table_rowtype := table_rowtype();

end table_trigger_helper;
/

Триггер уровня строки:

create or replace trigger row_level_trigger_name
  after insert or delete or update
  on table_name
  for each row
declare

  r_old table_trigger_helper.table_rowtype := NULL;
  r_new table_trigger_helper.table_rowtype := NULL;
  i pls_integer;

begin

 if update or deleting then
  r_old.column_one := :old.column_one
  ...
 end if;

 if update or inserting then
  r_new.column_one := :new.column_one
 end if;

  table_trigger_helper.v_old.extend();
  table_trigger_helper.v_new.extend();
  i := table_trigger_helper.v_old.last;

  table_trigger_helper.v_old( i ) := r_old;
  table_trigger_helper.v_new( i ) := r_new;  
end row_level_trigger_name;
/  

Триггер уровня оператора:

create or replace trigger statement_level_trigger_name
 after insert or delete or update
 on table_name
declare
begin
  --process through your new and old records;
  --table_trigger_helper.v_old
  --table_trigger_helper.v_new
end statement_level_trigger_name;
/
...