条件是重复密钥更新无法正常工作

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() 可以使其正确使用在创建新行时本应使用的任何值。