任务:编写一个触发器来记录tbl1
表中的所有更新,以供将来审计用户的操作。
表tbl1
:
id INT(11)
y SMALLINT(6)
country SMALLINT(6)
-- really here ~20 fields but only some of them have to be monitored
我将存储旧值和新值,每个更改的字段一行。日志的位置(在此示例中进行了简化):
CREATE TABLE z_log(
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
table_name CHAR(20) NOT NULL,
row_id INT(11) UNSIGNED NOT NULL,
field CHAR(20) NOT NULL,
old_val VARCHAR(255) NOT NULL DEFAULT '',
new_val VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (id)
)
我创建的触发器:
CREATE TRIGGER trigger1
AFTER UPDATE
ON tbl1
FOR EACH ROW
BEGIN
-- I'm interested in two fields only and if they were changed only
IF new.y != old.y THEN
SET @y = "('','tbl1',new.id,'y',old.y,new.y)";
END IF;
IF new.country != old.country THEN
SET @country = "('','tbl1',new.id,'country',old.country,new.country)";
END IF;
if @y != '' or @country != '' THEN
set @my_sql = concat('insert into z_lot values ', concat_ws(',', @y, @country), ';');
prepare stmt1 from @my_sql;
EXECUTE stmt1;
end if;
END
但我收到错误“存储函数或触发器中不允许使用动态 sql”。我可以通过使用大量分隔的插入来避免“执行”:一个用于字段“y”,一个用于字段“国家”,另外约 10 个用于其他字段,但会降低性能。
有没有其他快速的方法来只记录更改?谢谢你。
您可以使用蛮力 INSERT 更改触发器,如下所示:
我花了几天时间想出了一个存储过程来自动/动态地在 MariaDB(与 v 10.1.9 一起使用)中创建 UPDATE / DELETE 触发器,以审核更新和删除的所有更改。该解决方案使用 INFORMATION_SCHEMA 为您的每个表自动构建审计触发器。在更新时仅审计更改的列,而在删除时,所有历史记录都保留在审计中。
存储过程将为您提供一个 CREATE TRIGGER 脚本,您可以单独执行该脚本。
在下面的示例中,我们创建了一个包含两个表的测试数据库,tb_company 和 tb_auditdetail 将保存我们的审计日志。
上面的示例理所当然地认为,每个表都有 5 列:created、createdby、updated、updatedby、record_version。
但是,您可以根据需要以不同方式自定义存储过程 sp_maketrigger。sp 也受到增强和改进。
伦纳德·托纳
iLab马耳他
www.ilabmalta.com