使用触发器审计操作
Posted
技术标签:
【中文标题】使用触发器审计操作【英文标题】:Audit operations with a trigger 【发布时间】:2014-11-15 20:32:18 【问题描述】:我有一个在特定条件下触发的触发器,当我更新 EMPLOYEES table
中的一些数据时(特别是当 inserting
、deleting
和 updating
comm_pct
和 salary
时)所做的更改注册到下表中:
CREATE TABLE "HR"."AUDIT_E" ("USR" VARCHAR2(30 BYTE) DEFAULT USER,
"DATE" DATE DEFAULT SYSDATE,
"DML_TYPE" VARCHAR2), -- UPDATE, INSERT, DELETE
"OLD_EMPLOYEE_ID" NUMBER,
"OLD_FIRST_NAME" VARCHAR2,
...,--more fields
"OLD_JOB_ID" VARCHAR2,
"OLD_SALARY" NUMBER,
"OLD_COMMISSION_PCT" NUMBER,
"NEW_FIRST_NAME" VARCHAR2,
..., -- more fields!
"NEW_JOB_ID" VARCHAR2,
"NEW_SALARY" NUMBER,
"NEW_COMMISSION_PCT" NUMBER)
我的问题是:当updating rows
带有其他值(如email
带有comm_pct
和其他字段)时,我如何在AUDIT_E
中执行INSERT
(因为我必须将旧值和新值注册到其中) ,除了只更新comm_pct
和salary
)?因为我的触发器有以下结构:
IF DELETING THEN
--some actions
-- Insert into AUDIT_E(...) values...
ELSIF INSERTING THEN
--some actions
-- Insert into AUDIT_E(...) values...
ELSIF UPDATING ('a field') THEN --I have two of these
--some actions
-- Insert into AUDIT_E(...) values...comm_pct/salary
非常感谢你能帮助我,对不起我的英语。
编辑:当我在 inserting
、deleting
行和 updating
仅 comm_pct
和 salary
时,我的触发器运行良好,将更改注册到 audit_e
:
AUDIT_E:
ID |Oper|Old_Name|Old_job_id|Old_comm_pct|Old_Salary|New_name|New_job_id|New_comm_pct|New_salary
------------------------------------------------------------------------------------------------
1 |Ins | NULL | NULL | NULL | NULL |Kappa | SA_REP | 0.2 | 4980
2 |Upd | Kappa | SA_REP | 0.2 | 4980 | NULL | NULL | 0.3 | NULL
3 |Upd | Kappa | SA_REP | 0.3 | 4980 | NULL | NULL | NULL | 5000
4 |Del | Kappa | SA_REP | 0.3 | 4980 | NULL | NULL | NULL | NULL
但是,例如,当我更改 job_id(添加额外的 elsif 更新)时,更改会错误地保存到 audit_e 中:
AUDIT_E:
ID |Oper|Old_Name|Old_job_id|Old_comm_pct|Old_Salary|New_name|New_job_id|New_comm_pct|New_salary
------------------------------------------------------------------------------------------------
1 |Upd |Kappa | SA_REP | 0.2 | 4980 | NULL | NULL | NULL | NULL
我希望将这些更改保存到 audit_e 表中,如下所示:
AUDIT_E:
ID |Oper|Old_Name|Old_job_id|Old_comm_pct|Old_Salary|New_name|New_job_id|New_comm_pct|New_salary
------------------------------------------------------------------------------------------------
1 |Upd |Kappa | SA_REP | 0.2 | 4980 | NULL | IT_PROG | NULL | NULL
【问题讨论】:
恐怕我不明白你问的问题。您发布的触发器大纲似乎无效——如果您真的有ELSIF
子句,那么您不会想要所有END IF
的。如果您想拥有多个IF
语句,您将保留END IF
并将ELSIF
替换为IF
。但我不相信这是你要问的问题。
我更正了我发布的代码。我的想法是有一个历史表(在本例中为 AUDIT_E),它在员工表中注册所有使用 INSERT、UPDATE 和 DELETE 更改的值。但我的问题是我想注册我的更改,这些更改不仅会更改薪水或 comm_pct 的值,也不会在员工中添加或删除行
触发器在 EMPLOYEES 表上,不是吗?如果是,您拥有所有想要存储在 AUDIT_E 中的数据,不是吗?
触发器正在对员工执行。但我想将数据存储到 audit_e。当我插入一行、删除一行以及更新 comm_pct 和/或薪水时,我可以存储数据。但我希望我的触发器(在 audit_e 中)注册员工所做的其他更改(如更改 job_id、first_name 等)
【参考方案1】:
我仍然不确定我是否理解了这个问题。我的猜测是你只想要类似的东西
CREATE OR REPLACE TRIGGER trigger_name
AFTER INSERT OR UPDATE OR DELETE
ON employees
FOR EACH ROW
BEGIN
INSERT INTO audit_e( dml_type,
old_employee_id, new_employee_id,
old_first_name, new_first_name,
...
)
VALUES( CASE WHEN deleting
THEN 'D'
WHEN inserting
THEN 'I'
WHEN updating
THEN 'U'
ELSE 'X'
END,
:old.employee_id, :new.employee_id,
:old.first_name, :new.first_name,
...
);
END;
也就是说,我不清楚您为什么每次都将新旧数据都存储在审计表中。 old_*
值始终与前一行中的 new_
值相同。将new_
值存储在审计表中通常是有意义的。
【讨论】:
是的,我需要类似的东西,但仅限于更新情况。我认为添加另一个 ELSIF 子句和一个 INSERT 值可以注册我想要的更改。但是当我更改一些不是 comm_pct 和薪水的值(例如 job_id)时,我的审计表没有正确记录这些更改(:old 值是正确的,但 :new 值在表中保持为空)如果我将该块放入我的代码中。 @RyuukoMatoi - 那我还是不明白你想问的问题。在我的回答中,触发器中没有IF
语句,每次修改都会记录所有旧值和新值。如果这不是您的目标,那么我不明白这个问题 - 您可以编辑您的问题以包含一个可重现的测试用例,以准确显示您想要发生的事情吗?
现在我编辑了我的问题,更详细地解释了我想要的结果。我很抱歉英语不好。我希望你能明白我想做什么。
@RyuukoMatoi - 我发布的触发器结果与您想要的结果有何不同?我的触发器有 0 个“IF”语句。如果你想让你的生活复杂化,你可以为每一个可以更新的列添加一个“Elsif”。但是,我认为没有任何理由这样做。
我忘了提及,但我的触发器是 BEFORE INSERT UPDATE DELETE。好吧,当我更新 comm_pct 和薪水时,这些值必须保留触发器的某些条件。我会尝试做类似的事情并查看它是如何工作的。感谢您的帮助以上是关于使用触发器审计操作的主要内容,如果未能解决你的问题,请参考以下文章