条件是重复密钥更新无法正常工作
Conditional on duplicate key update not working correctly
我需要将我的 created_on
日期时间字段值更新为 NOW()
只有当 is_active
字段的旧值是 0 并且它更改为 1 时。
+-----------+---------+-----------+---------------------+---------------------+
| device_id | user_id | is_active | created_on | last_modified_on |
+-----------+---------+-----------+---------------------+---------------------+
| 5 | 5 | 0 | 2016-06-05 03:31:48 | 2016-06-05 03:31:48 |
这是我目前得到的:
INSERT INTO `device2users`
(`device_id`, `user_id`, `is_active`, `created_on`, `last_modified_on`)
VALUES
(5, 5, 1, NOW(), NOW())
ON DUPLICATE KEY UPDATE
`created_on` = CASE WHEN `is_active` <> 0 THEN VALUES(`created_on`) ELSE NOW() END,
`is_active`=1, `last_modified_on`=NOW();
但它不起作用,created_on
字段的值始终设置为 NOW()
。
编辑 1:
我想将 created_on
字段的值更新为 NOW() ON DUPLICATE KEY
,前提是 is_active
字段的值之前是 0
并且是 1
在指定的查询中。
编辑 2:
我正在根据@ring bearer 的回答使用以下查询。但我得到:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '== '0' && NEW.is_active == '1' THEN
这是我正在使用的确切查询。
DELIMITER //
CREATE TRIGGER created_on_after_update
AFTER UPDATE
ON `acd_device2users` FOR EACH ROW
BEGIN
IF OLD.is_active == '0' && NEW.is_active == '1' THEN
SET `created_on`=NOW();
END IF;
END; //
DELIMITER ;
我建议使用更新触发器来使其正常工作。在该触发器中,您将跟踪对 is_active
字段的更改并将必填字段设置为必填值。示例:
DELIMITER //
CREATE TRIGGER created_on_after_update
BEFORE INSERT
ON my_table FOR EACH ROW
BEGIN
IF (NEW.is_active = '1') THEN
//Set required change.
END IF;
END; //
DELIMITER ;
在插入过程中,您只需检查 NEW.is_active 并按上面所示做出决定。
您只需要 created_on
,而您有 values(created_on)
。 values returns 如果没有重复键(在你的例子中是 now()),列将被设置为的值,而不是旧值。
更新部分中的列名称将 return 如果您在设置它们之前使用它们的旧值。因此,如果 is_active 从 0 变为 1,则仅更改 created_on,请执行以下操作:
ON DUPLICATE KEY UPDATE
created_on = CASE WHEN is_active=0 && VALUES(is_active)=1 THEN VALUES(created_on) ELSE created_on END,
is_active = VALUES(is_active),
last_modified_on = VALUES(last_modified_on);
使用 VALUES 而不是硬编码 1 或 NOW() 可以使其正确使用在创建新行时本应使用的任何值。
我需要将我的 created_on
日期时间字段值更新为 NOW()
只有当 is_active
字段的旧值是 0 并且它更改为 1 时。
+-----------+---------+-----------+---------------------+---------------------+
| device_id | user_id | is_active | created_on | last_modified_on |
+-----------+---------+-----------+---------------------+---------------------+
| 5 | 5 | 0 | 2016-06-05 03:31:48 | 2016-06-05 03:31:48 |
这是我目前得到的:
INSERT INTO `device2users`
(`device_id`, `user_id`, `is_active`, `created_on`, `last_modified_on`)
VALUES
(5, 5, 1, NOW(), NOW())
ON DUPLICATE KEY UPDATE
`created_on` = CASE WHEN `is_active` <> 0 THEN VALUES(`created_on`) ELSE NOW() END,
`is_active`=1, `last_modified_on`=NOW();
但它不起作用,created_on
字段的值始终设置为 NOW()
。
编辑 1:
我想将 created_on
字段的值更新为 NOW() ON DUPLICATE KEY
,前提是 is_active
字段的值之前是 0
并且是 1
在指定的查询中。
编辑 2:
我正在根据@ring bearer 的回答使用以下查询。但我得到:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '== '0' && NEW.is_active == '1' THEN
这是我正在使用的确切查询。
DELIMITER //
CREATE TRIGGER created_on_after_update
AFTER UPDATE
ON `acd_device2users` FOR EACH ROW
BEGIN
IF OLD.is_active == '0' && NEW.is_active == '1' THEN
SET `created_on`=NOW();
END IF;
END; //
DELIMITER ;
我建议使用更新触发器来使其正常工作。在该触发器中,您将跟踪对 is_active
字段的更改并将必填字段设置为必填值。示例:
DELIMITER //
CREATE TRIGGER created_on_after_update
BEFORE INSERT
ON my_table FOR EACH ROW
BEGIN
IF (NEW.is_active = '1') THEN
//Set required change.
END IF;
END; //
DELIMITER ;
在插入过程中,您只需检查 NEW.is_active 并按上面所示做出决定。
您只需要 created_on
,而您有 values(created_on)
。 values returns 如果没有重复键(在你的例子中是 now()),列将被设置为的值,而不是旧值。
更新部分中的列名称将 return 如果您在设置它们之前使用它们的旧值。因此,如果 is_active 从 0 变为 1,则仅更改 created_on,请执行以下操作:
ON DUPLICATE KEY UPDATE
created_on = CASE WHEN is_active=0 && VALUES(is_active)=1 THEN VALUES(created_on) ELSE created_on END,
is_active = VALUES(is_active),
last_modified_on = VALUES(last_modified_on);
使用 VALUES 而不是硬编码 1 或 NOW() 可以使其正确使用在创建新行时本应使用的任何值。