1

我試圖讓有以下行爲的查詢MySQL的問題:與IF語句和TIMESTAMP

  • 如果插入新行:id = NULL或行,其中id = :id還不存在。
  • 更新現有的行,如果其中id = :id已存在的行。
  • 設置的activatedNOW()如果值:中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'

任何人都可以解釋我做錯了什麼?並(最好)解釋如何解決它?

回答

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上更新列。

+0

嘿,我沒有想到!我現在要試試:) –

+1

好的!有用!感謝Joachim! –

0

您不在ON DUPLICATE KEY UPDATE子句中指定id(或鍵列)。

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

例如,如果列中的被聲明爲UNIQUE和包含值 1,下列兩個語句具有相同的效果:

INSERT INTO表(一, b,c)VALUES(1,2,3)在重複密鑰更新 c = c + 1;

UPDATE table 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 
+0

實際上,「id = LAST_INSERT_ID(id)」部分是有意的,它確保我可以檢索更新行的id。 (這也在mysql文檔中描述) –