Sql 审计表触发器
尝试创建触发器,以便在对基表进行更改之前使用旧数据填充审核表Sql 审计表触发器,sql,triggers,oracle12c,Sql,Triggers,Oracle12c,尝试创建触发器,以便在对基表进行更改之前使用旧数据填充审核表 CREATE OR REPLACE TRIGGER populate_audit_table BEFORE INSERT OR UPDATE OF cost, retail OR DELETE ON books REFERENCING NEW as new OLD as old FOR EACH ROW DECLARE dml_operation varchar2(1) := CASE WHEN UPDATING THEN '
CREATE OR REPLACE TRIGGER populate_audit_table
BEFORE INSERT OR UPDATE OF cost, retail OR DELETE
ON books
REFERENCING NEW as new OLD as old
FOR EACH ROW
DECLARE
dml_operation varchar2(1) :=
CASE WHEN UPDATING THEN 'U'
WHEN DELETING THEN 'D'
ELSE 'I'
END;
BEGIN
INSERT INTO cost_retail_history
(isbn
,title
,pubid
,pubdate
,cost
,retail
,discount
,category
,dml_operation)
SELECT
(old.isbn
,old.title
,old.pubid
,old.pubdate
,old.cost
,old.retail
,old.discount
,old.category
,new.dml_operation)
FROM BOOKS;
end;
我得到以下错误:
错误:触发器填充\u审核\u表
行/Col:8/7 PL/SQL:SQL语句被忽略
行/列:20/13 PL/SQL:ORA-00907:缺少右括号
我还尝试在INSERT INTO中使用值,而不是指定源表(“从书本中”)
我得到以下错误:
行/Col:8/7 PL/SQL:SQL语句被忽略
行/列:27/18 PL/SQL:ORA-00984:此处不允许使用列
我读了又读,所以我觉得我错过了一些简单的东西,只是需要一个正确的方向
谢谢
编辑:
我放弃了dml_操作,因为这不是必需的,并遵循了下面的建议,但仍然会出现错误:
当前版本:
CREATE OR REPLACE TRIGGER cost_retail_history
BEFORE INSERT
OR UPDATE OF cost, retail
OR DELETE
ON books
REFERENCING NEW as new OLD as old
FOR EACH ROW
BEGIN
CASE
WHEN INSERTING THEN
INSERT INTO cost_retail_history
(isbn
,title
,pubid
,pubdate
,cost
,retail
,discount
,category)
VALUES
(:new.isbn
,:new.title
,:new.pubid
,:new.pubdate
,:new.cost
,:new.retail
,:new.discount
,:new.category)
WHEN UPDATING cost, retail OR DELETING THEN
INSERT INTO cost_retail_history
(isbn
,title
,pubid
,pubdate
,cost
,retail
,discount
,category)
VALUES
(:old.isbn
,:old.title
,:old.pubid
,:old.pubdate
,:old.cost
,:old.retail
,:old.discount
,:old.category);
END CASE;
END;
我得到了错误信息:
错误:触发成本\零售\历史记录
行/Col:4/9 PL/SQL:SQL语句被忽略
行/Col:22/5 PL/SQL:ORA-00933:SQL命令未正确结束
我不能确切地说出错误在哪一行,因为这表明它与:
…或删除
及
…,:新标题
这对我来说毫无意义。如果您正在执行
插入。。。选择…
则列列表周围不应有括号;i、 e:
INSERT INTO cost_retail_history
(isbn
...
,dml_operation)
SELECT
old.isbn
...
,new.dml_operation
FROM BOOKS;
但是您不应该从触发器所针对的表中进行选择,部分原因是您将得到一个变异表错误,并且您正在尝试为基表中的每一行插入一个审计行;但主要是因为你已经掌握了你需要的所有信息
使用values
类,您需要在旧值/新值前面加一个冒号:
....VALUES
(:old.isbn
,:old.title
,:old.pubid
,:old.pubdate
,:old.cost
,:old.retail
,:old.discount
,:old.category
,:new.dml_operation);
end;
Oracle有内置的审计工具,但这大概是一个练习
我不能确切地说出错误在哪一行,因为这表明
这可能与触发器有点混淆,因为它们是SQL和PL/SQL的混合体。因为您会遇到PL/SQL错误,所以行编号从PL/SQL部分的开头开始,因此这里的BEGIN
是第1行,INSERT
是第4行<代码>更新时…是第22行
这些新错误只是因为第一条INSERT
语句末尾没有分号:
,:new.discount
,:new.category);
-----------------------^
WHEN UPDATING cost, retail OR DELETING THEN
INSERT INTO cost_retail_history
针对第22行报告错误,因为它希望看到分号的位置是
WHEN
,并且它看到上一个SQL命令的第一个点尚未完成。第4行的错误是指出未结束命令的起始位置;因此,对于一个实际问题,您收到了两条消息。我听从了亚历克斯·普尔的建议,但我仍然不在那里。谢谢你的回答,它澄清了我的参考哪里出错了。我更新了我的回答,以涵盖新的错误,并解释错误消息中的行号。
,:new.discount
,:new.category);
-----------------------^
WHEN UPDATING cost, retail OR DELETING THEN
INSERT INTO cost_retail_history