在sql server中触发触发器时,会创建2个临时表。一个是inserted表,其中包含触发器所属的原始表的行,其中发生了插入或更新(它包含:NEW值);另一个是已删除的表,它同样包含OLD值。
在sql Server中,可以在触发器中使用这些表,以便获得有关OLD和NEW值的信息。 (为了做一个简单的例子:可以在触发器内部进行“SELECT * FROM INSERTED”,以便选择已进行更新的所有行或插入时所有插入的行)。
关于这一点很酷的是,它可以动态调用:NEW.value和:OLD.value,如果像我的情况一样,我想在更多的表上使用相同的触发器(也是不同的一个另一个)。
Oracle pl sql有类似内容吗?
答案 0 :(得分:1)
我认为您正在审核该表,请查找有关插入,更新和删除审核的触发器
编辑:由于phantom
建议您在插入审计表之前需要检查每个列的新值和旧值。这样您就可以实现列值的更改。但是,您需要在审计中插入多行table,如果已经更新了同一条记录的多列。
我的想法是在更新/删除/插入审计表之前创建相同记录的副本。当您需要更改时,根据source_action / source_rowid与审计表中的上一条记录进行比较
CREATE TABLE table_for_audit
(
col1 NUMBER,
col2 NUMBER,
col3 NUMBER,
cre_date DATE,
cre_user VARCHAR2 (200)
);
CREATE TABLE audit_table
(
col1 NUMBER,
col2 NUMBER,
col3 NUMBER,
cre_date DATE,
cre_user VARCHAR2 (200),
source_action VARCHAR2 (1),
source_rowid
);
CREATE OR REPLACE TRIGGER trg_table_audit
BEFORE INSERT OR UPDATE OR DELETE
ON table_for_audit
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_source_action VARCHAR2 (1);
BEGIN
IF INSERTING
THEN
v_source_action := 'I';
v_source_rowid := :NEW.ROWID;
ELSIF UPDATING
THEN
v_source_action := 'U';
v_source_rowid := :OLD.ROWID;
ELSIF DELETING
THEN
v_source_action := 'D';
v_source_rowid := :OLD.ROWID;
END IF;
IF INSERTING OR UPDATING
THEN
INSERT INTO audit_table (col1,
col2,
col3,
cre_date,
cre_user,
source_action,
source_rowid)
VALUES (:NEW.col1,
:NEW.col2,
:NEW.col3,
SYSDATE,
SYS_CONTEXT ('USERENV', 'CURRENT_USER'),
v_source_action,
v_source_rowid);
ELSIF DELETING
THEN
INSERT INTO audit_table (col1,
col2,
col3,
cre_date,
cre_user,
source_action,
source_rowid)
VALUES (:OLD.col1,
:OLD.col2,
:OLD.col3,
SYSDATE,
SYS_CONTEXT ('USERENV', 'CURRENT_USER'),
v_source_action,
v_source_rowid);
END IF;
END;
/
如果我的理解错误,请纠正。谢谢
答案 1 :(得分:0)
您希望在触发器中使用referencing
子句。官方图表为here,但我发现this page更好地解释了它。
基本上,您可以创建触发器:
CREATE OR REPlACE TRIGGER trigger_name
AFTER DELETE OR INSERT OR UPDATE
ON table_name
REFERENCING OLD AS oldAlias AND NEW AS newAlias
...
现在,您可以将预触发和后触发值引用为:oldAlias.column_name
和:newAlias.column_name
。
例如,这将检查personnel_type值是否从1更新为2:
IF :oldAlias.personnel_type = 1 AND :newAlias.personnel_type = 2 THEN
-- do something
END IF ;
从我可以收集的内容来看,听起来你想要创建一个单独的触发器来监控多个表。 Oracle触发器不能像那样工作。您希望监控的每个表都必须有自己独立的触发器。但是,您可以: