Вы можете проверить, изменилось ли каждое значение как часть вставки в таблицу истории:
create trigger users_trigger
before insert or update on users
for each row
begin
insert into users_history_changes (id, first_name, last_name, age, timestamp_changes)
values (:new.id,
case when :old.first_name is null or :new.first_name != :old.first_name then :new.first_name end,
case when :old.last_name is null or :new.last_name != :old.last_name then :new.last_name end,
case when :old.age is null or :new.age != :old.age then :new.age end,
systimestamp);
end;
/
Вероятно, бесполезно проверять, изменилось ли значение на null, так как это не будет очень полезной историей, поэтому я проверил только из null.И даже эти тесты могут / должны быть расширены для охвата крайних случаев, например, для проверки того, что что-то действительно изменилось.
В любом случае, со следующими утверждениями:
insert into users
select 1, 'Raul', 'Peres', 25 from dual
union all select 2, 'Francis', 'Lotters', 40 from dual
union all select 3, 'Maria', 'Lopez', 39 from dual;
update users set last_name = 'Felipes' where id = 1;
update users set first_name = 'Pedro' where id = 1;
update users set age = 30 where id = 1;
update users set first_name = 'Maria', last_name = 'Sanchez', age = 40 where id = 3;
таблица истории заканчивается:
ID FIRST_NAME LAST_NAME AGE TIMESTAMP_CHANGES
---------- ---------- ---------- ---------- ----------------------------
1 Raul Peres 25 19-JUN-19 20.02.33.470409000
2 Francis Lotters 40 19-JUN-19 20.02.33.473139000
3 Maria Lopez 39 19-JUN-19 20.02.33.473183000
1 Felipes 19-JUN-19 20.02.33.548101000
1 Pedro 19-JUN-19 20.02.33.594305000
1 30 19-JUN-19 20.02.33.640293000
3 Sanchez 40 19-JUN-19 20.02.33.688710000
db <> fiddle
В качестве альтернативы, если вы хотите, чтобы одна строка на каждое измененное значение, вы могли бы использовать updating
предложение:
create trigger users_trigger
before insert or update on users
for each row
begin
if inserting then
insert into users_history_changes (id, first_name, last_name, age, timestamp_changes)
values (:new.id, :new.first_name, :new.last_name, :new.age, systimestamp);
end if;
if updating ('FIRST_NAME') then
insert into users_history_changes (id, first_name, timestamp_changes)
values (:new.id, :new.first_name, systimestamp);
end if;
if updating ('LAST_NAME') then
insert into users_history_changes (id, last_name, timestamp_changes)
values (:new.id, :new.last_name, systimestamp);
end if;
if updating ('AGE') then
insert into users_history_changes (id, age, timestamp_changes)
values (:new.id, :new.age, systimestamp);
end if;
end;
/
, но при этом будет создана строка для значений, которые «изменены» на то же значение, если только вы не добавите дополнительную логику для проверки фактических изменений - проверка updating()
заключается в том, что обновлениеоператор включил столбец в свой список set
. дб <> скрипка