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

时间:2016-06-05 07:51:33

标签: mysql conditional on-duplicate-key

仅当created_on字段的旧值为0且更改为1时,我才需要将NOW()日期时间字段值更新为is_active

+-----------+---------+-----------+---------------------+---------------------+
| 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 ;

2 个答案:

答案 0 :(得分:0)

我建议使用更新触发器来实现此功能。在该触发器中,您将跟踪对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并做出如上所示的决定。

答案 1 :(得分:0)

您只需要created_on values(created_on)。如果没有重复键(在您的情况下是now()),则值返回列已设置的值,而不是旧值。

如果在设置之前使用它们,则更新部件中的

列名称将返回其旧值。因此,如果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()可以正确使用在创建新行时使用的任何值。