我正在尝试进行具有以下行为的查询:
:id = NULL
或id = :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'
的值始终保持不变。
任何人都可以解释我做错了什么吗?并且(最好)解释如何修复它?
答案 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