我正在尝试创建一个触发器,它将捕获在更新前后更新表中任何列时将发生的任何事件,假设我有4列:
first_name address city country
假设我已编辑first_name
,请说Jack to Henk
。
它应该在另一个表中插入命令(i.e. update) ,time , description
但是在描述中我希望它写杰克被当前用户(i.e using the current-user () function)
更改为John,如果它是从Mechinkova更新到Tostov的城市,它应该与其他专栏做同样的事情。
我知道我想要在触发器中添加concat函数,我希望它像这样:例如:
DROP TRIGGER IF EXISTS adminpanel.soft//
CREATE TRIGGER adminpanel.soft BEFORE UPDATE ON adminpanel.aggrement
FOR EACH ROW
BEGIN
INSERT INTO adminpanel.aggretrigger(cmd, time, cmd_user, last_name, city) VALUES("INSERT", NOW(), CURRENT_USER(), new.last_name, new.city);
END
//
答案 0 :(得分:0)
您要求的是审核触发器。它很容易实现。
我们先来稍微修改一下你的主表。我们将id
数据类型的integer
字段添加为表的主键,因此您的表格如下所示:
tablename
( id integer PK
, first_name varchar
, address varchar
, city varchar
, country varchar
)
现在,你需要一个表,比如UNIVERSAL_AUDIT_ENTRY
表,它将存储对模式中数据所做的更改。
根据我的经验,我建议您按如下方式创建此表:
universal_audit_entry
( universal_audit_entryid integer PK
, table_name varchar -- captures the name of the table
, column_name varchar -- captures the name of the column
, entry_type varchar -- captures the event, e.g., 'INSERT' or 'UPDATE'
, primary_key_value integer -- captures, e.g., the value in tblename.id
, from_str varchar -- captures the value that was present before
, to_str varchar -- captures the value that was changed into
, timestamp datetime -- captures the timestamp of the event
, username varchar -- captures the name of user
)
现在准备好universal_audit_entry
表,你的触发器应该看起来像:
CREATE TRIGGER adminpanel.soft
BEFORE UPDATE ON adminpanel.aggrement
FOR EACH ROW
BEGIN
IF UPDATING(first_name) THEN
INSERT INTO universal_audit_entry VALUES
( 123 -- example for universal_audit_entryid
, 'TABLENAME'
, 'FIRST_NAME'
, 'UPDATE'
, new.id
, old.first_name
, new.first_name
, current_timestamp()
, current_user);
END IF;
END;
//
您可以使用类似的逻辑来审核同一表和其他表中的更多列。
注意:强>
此代码未经过测试。我在这里添加它仅用于说明目的。触发器的代码不应该直接使用。
new
和old
是在更新语句期间生成的伪记录。这些记录对应于正在更新的行。 :new
表示更新语句运行后的行,:old
表示更新语句运行之前的行。这适用于Oracle。请确保它是否也适用于MySQL。
修改强>
您可以阅读有关MySQL触发器here的更多信息。详细了解审计跟踪here和this SO question。