我知道,这个问题已经构思了很多次,但我需要你的建议:)
有2个表:
| item |income |create_user |create_date |last_update_user | update_time|
|------|-------|------------|-------------------|-----------------|------------|
| 1 | 100 |duck |05-19-2016 |human |05-19-2016 |
| 2 | 250 |dog |05-19-2016 |human |05-19-2016 |
| 3 | 210 |cat |05-20-2016 |human |05-19-2016 |
| item |change_id|last_inc|new_inc |user_update|update_date|operation |
|------|---------|--------|----------|-----------|-----------|------------|
| 1 | 1 |null |05-19-2016|duck |05-19-2016 |I |
| 2 | 2 |null |05-19-2016|dog |05-19-2016 |I |
| 3 | 33 |null |05-20-2016|cat |05-19-2016 |I |
任务是:当某人进行插入,更新或删除时,触发器必须在表格 Sale_income_audit (操作类型 - 列'操作)上插入上面的记录。并且同时必须更新表格 Sale_income (last_update_user和update_time)。 我这样做了:创建包含3个变量的包:
create or replace package Sale_income_var as
v_old_income BINARY_INTEGER := null;
v_new_income BINARY_INTEGER := null;
v_item BINARY_INTEGER := null;
END Sale_income_var;
和2个触发器
第一
create or replace trigger audit_income_IUD
after insert or update or delete on Sale_income
for each row
begin
.
.
elsif updating then
Sale_income_var.v_old_income := :old.income;
Sale_income_var.v_new_income := :new.income;
if Sale_income_var.v_item is null then
Sale_income_var.v_item := :old.item;
DBMS_OUTPUT.PUT_LINE(Sale_income_var.v_item);
end if;
.
.
end if;
end audit_income_IUD;
第二
create or replace trigger sale_income_au
after update of income on Sale_income
begin
update Sale_income set last_update_user = user, last_update_date = sysdate
where item = Sale_income_var.v_item;
INSERT into Sale_income_audit (item,
change_id,
last_income,
new_income,
user_update,
update_date,
operation)
VALUES (Sale_income_var.v_item,
auto_incr.NEXTVAL,
Sale_income_var.v_old_income,
Sale_income_var.v_new_income,
user,
sysdate,
'U');
Sale_income_var.v_item := null;
end sale_income_au;
它有效,但我失去了解决方案的错误。因为从'general'触发器更新块移动到另一个触发器并且这个魔法带变量它不好,我是对的吗?
您将如何决定此任务?您在我的解决方案中会改变什么? 谢谢你的帮助:)
答案 0 :(得分:1)
只需使用一个BEFORE
触发器就可以完成
在允许触发器修改表列的NEW值之前,这些修改后的值存储在表中,因此可以通过这种方式更新last_update_user
和update_time
列。
create or replace trigger audit_income_IUD
BEFORE insert or update or delete on Sale_income
for each row
declare
operation_type char;
begin
if updating or inserting then
:new.update_time := sysdate;
:new.last_update_user := user;
end if;
CASE
WHEN updating THEN operation_type := 'U';
WHEN inserting THEN operation_type := 'I';
WHEN deleting THEN operation_type := 'D';
END CASE;
INSERT into Sale_income_audit (item,
change_id,
last_income,
new_income,
user_update,
update_date,
operation)
VALUES (:old.item,
auto_incr.NEXTVAL,
:old.income,
:new.income,
user,
sysdate,
operation_type);
end;
/
答案 1 :(得分:0)
答案似乎很简单。需要在每行之后使用并添加块'更新'
:new.last_update_user := user;
:new.last_update_date := sysdate;
我们可以限制为一个没有包装的触发器!