[英]MySQL after update trigger with number of affected rows condition
In MySQL, I want to create a trigger with AFTER UPDATE
triggering event for my user
table.在 MySQL 中,我想为我的
user
表创建一个带有AFTER UPDATE
触发事件的触发器。
In next, I have a table named user_log
which is use to store the modifications that occurred on the parent table user
after any update commands.接下来,我有一个名为
user_log
的表,用于存储在执行任何更新命令后对父表user
进行的修改。
So, data in user_log
table need be as follows:所以,
user_log
表中的数据需要如下:
select * from user_log;
+--------+---------+----------------------------+---------------+----------------+---------------------+------+
| log_id | user_id | action | old_data | new_data | changed_date | read |
+--------+---------+----------------------------+---------------+----------------+---------------------+------+
| 1 | 10 | Changed yyy's name | yyy | xxx | 2022-06-20 14:06:56 | no |
| 2 | 10 | Changed xxx's address | No.111, | No.112, | 2022-06-20 19:07:38 | no |
| 3 | 10 | Changed xxx's city | Old City Name | New City Name | 2022-06-20 19:07:38 | no |
| 4 | 10 | Changed xxx's phone number | 011-5000000 | 011-4000000 | 2022-06-20 19:07:38 | no |
+--------+---------+----------------------------+---------------+----------------+---------------------+------+
As you can see from the data in the table above, it will update several columns at once.从上表中的数据可以看出,它会同时更新几列。 So I created my triger as follows, and its working for me.
所以我按如下方式创建了触发器,它对我有用。
DELIMITER $$
DROP TRIGGER IF EXISTS `user_log` ;
$$
CREATE TRIGGER `user_log`
AFTER UPDATE ON `user`
FOR EACH ROW
BEGIN
IF OLD.name <> NEW.name THEN
INSERT INTO user_log (user_id,action,old_data,new_data)
VALUES(
NEW.user_id
, CASE
WHEN (NEW.name <> OLD.name)
THEN CONCAT('Changed ', OLD.name, "'s ", 'name')
ELSE ''
END
, CASE WHEN (NEW.name <> OLD.name) THEN OLD.name ELSE '' END
, CASE WHEN (NEW.name <> OLD.name) THEN NEW.name ELSE '' END
);
END IF;
IF OLD.address <> NEW.address THEN
INSERT INTO user_log (user_id,action,old_data,new_data)
VALUES(
NEW.user_id
, CASE
WHEN (NEW.address <> OLD.address)
THEN CONCAT('Changed ', OLD.name, "'s ", 'address')
ELSE ''
END
, CASE WHEN (NEW.address <> OLD.address) THEN OLD.address ELSE '' END
, CASE WHEN (NEW.address <> OLD.address) THEN NEW.address ELSE '' END
);
END IF;
IF OLD.city <> NEW.city THEN
INSERT INTO user_log (user_id,action,old_data,new_data)
VALUES(
NEW.user_id
, CASE
WHEN (NEW.city <> OLD.city)
THEN CONCAT('Changed ', OLD.name, "'s ", 'city')
ELSE ''
END
, CASE WHEN (NEW.city <> OLD.city) THEN OLD.city ELSE '' END
, CASE WHEN (NEW.city <> OLD.city) THEN NEW.city ELSE '' END
);
END IF;
IF OLD.phone <> NEW.phone THEN
INSERT INTO user_log (user_id,action,old_data,new_data)
VALUES(
NEW.user_id
, CASE
WHEN (NEW.phone <> OLD.phone)
THEN CONCAT('Changed ', OLD.name, "'s ", 'phone number')
ELSE ''
END
, CASE WHEN (NEW.phone <> OLD.phone) THEN OLD.phone ELSE '' END
, CASE WHEN (NEW.phone <> OLD.phone) THEN NEW.phone ELSE '' END
);
END IF;
END$$
DELIMITER ;
My problem is, I have a lot more columns in the user table.我的问题是,我在用户表中有更多的列。 Like I said, all columns or several of them are updated at once.
就像我说的,所有专栏或其中的几个专栏都会立即更新。
In that case I have to add a large amount of INSERT query to my trigger.在这种情况下,我必须向我的触发器添加大量 INSERT 查询。 So here I would like to know if there is another suitable way to do this.
所以在这里我想知道是否有另一种合适的方法来做到这一点。
I also tried it in this way.我也是这样试的。 But its working only for one column.
但它只适用于一列。
DROP TRIGGER IF EXISTS `user_log`;
CREATE TRIGGER IF NOT EXISTS `user_log`
AFTER UPDATE ON user
FOR EACH ROW
INSERT INTO user_log (user_id,action,old_data,new_data)
VALUES (
NEW.user_id
, CASE
WHEN (NEW.name <> OLD.name)
THEN CONCAT('Changed ', OLD.name, "'s ", 'name')
WHEN (NEW.address <> OLD.address)
THEN CONCAT('Changed ', OLD.name, "'s ", 'address')
WHEN (NEW.city <> OLD.city)
THEN CONCAT('Changed ', OLD.name, "'s ", 'city')
WHEN (NEW.phone <> OLD.phone)
THEN CONCAT('Changed ', OLD.name, "'s ", 'phone number')
ELSE ''
END
, CASE
WHEN (NEW.name <> OLD.name)
THEN OLD.name
WHEN (NEW.address <> OLD.address)
THEN OLD.address
WHEN (NEW.city <> OLD.city)
THEN OLD.city
WHEN (NEW.phone <> OLD.phone)
THEN OLD.phone
ELSE ''
END
, CASE
WHEN (NEW.name <> OLD.name)
THEN NEW.name
WHEN (NEW.address <> OLD.address)
THEN NEW.address
WHEN (NEW.city <> OLD.city)
THEN NEW.city
WHEN (NEW.phone <> OLD.phone)
THEN NEW.phone
ELSE ''
END
);
Thank you.谢谢你。
Pattern:图案:
CREATE TRIGGER ...
...
BEGIN
INSERT INTO user_log (user_id,action,old_data,new_data)
SELECT NEW.user_id,
CONCAT('Changed ', OLD.name, "'s ", columnname),
oldvalue,
newvalue
FROM ( SELECT 'name' columnname, OLD.name oldvalue, NEW.name newvalue
UNION ALL
SELECT 'address', OLD.address, NEW.address
UNION ALL
SELECT 'city', OLD.city, NEW.city
UNION ALL
SELECT 'phone', OLD.phone, NEW.phone
) data
WHERE NOT oldvalue <=> newvalue;
END;
Also you may use ROW() constructor instead of SELECT.. UNION ALL.您也可以使用 ROW() 构造函数代替 SELECT.. UNION ALL。
https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=c63b122abedf9481d72129bee0d2d87d https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=c63b122abedf9481d72129bee0d2d87d
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.