IF语句和TIMESTAMP的MySQL问题

时间:2013-05-20 20:29:03

标签: mysql if-statement timestamp string-comparison on-duplicate-key

我正在尝试进行具有以下行为的查询:

  • 如果:id = NULLid = :id尚不存在的行,请插入新行。
  • 如果id = :id已存在的行,则更新现有行。
  • 如果符合以下条件,请将activated的值设置为NOW()
    • status <> :status的当前值。 (aka。如果status的值将被更改)
    • :status = 'active'的值。 (又名status的新值将为'active'

为了做到这一点,我做了以下准备陈述:

INSERT INTO test
  (`id`, `title`, `status`, `activated`)
VALUES
  (:id, :title, :status, NULL)
ON DUPLICATE KEY UPDATE
  id = LAST_INSERT_ID(id),
  status = VALUES(status),
  activated = IF(status <> VALUES(status) AND VALUES(status) = 'active', 
               NOW(), activated);

据我所知,这个陈述准确地描述了所需的逻辑。但是,无论activated的值是否更改为status'active'的值始终保持不变。

任何人都可以解释我做错了什么吗?并且(最好)解释如何修复它?

2 个答案:

答案 0 :(得分:1)

这个问题非常类似于SQL,你在比较它之前就分配了状态;

status=VALUES(status),                                 -- assign so they're equal
activated=IF(status <> VALUES(status) AND              -- compare, always equal
      VALUES(status) = 'active', NOW(), activated);

只需撤销作业,事情就可以了。

INSERT INTO test
  (`id`, `title`, `status`, `activated`)
VALUES
  (:id, :title, :status, NULL)
ON DUPLICATE KEY UPDATE
  id=LAST_INSERT_ID(id),
  activated=IF(status <> VALUES(status) AND 
               VALUES(status) = 'active', NOW(), activated),
  status=VALUES(status);

顺便说一下,您只需要指定实际更改的列,无需在更新时设置id

答案 1 :(得分:0)

您没有在ON DUPLICATE KEY UPDATE子句中指定id(或键列)。

来自:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

  

例如,如果列a声明为UNIQUE并包含该值   1,以下两个陈述具有相同的效果:

     
    

INSERT INTO表(a,b,c)VALUES(1,2,3)在DUPLICATE KEY UPDATE     C = C + 1;

         

UPDATE表SET c = c + 1 WHERE a = 1;

  

您目前拥有的内容很可能是更改插入数据库的最后一行而不是重复的键行。阅读LAST_INSERT_ID()上的文档: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

回顾你的问题,我知道我并没有真正/完全回答你的问题。我部分试图了解用例是什么。在我通过代码创建用户的情况下,如果是管理员创建用户,我只需将帐户设置为活动(并设置激活的列,如果有的话)。如果是通过网络表单创建帐户的用户,则会将其设置为待处理状态,直到他们使用其电子邮件中的链接为止。电子邮件中的链接使用激活码,允许我执行以下操作:

update user set status='active' activated=NOW() where code=:activation_code