2015-12-21 52 views
-1

我有一個表:MySQL的:當唯一索引碰撞更新行

CREATE TABLE `IDM_USER_MEASURE` (
    `USER_ID` bigint(20) NOT NULL, 
    `MEASURE_ID` bigint(20) NOT NULL, 
    `MEASURE_DATE` int(11) NOT NULL, 
    `MEASURE_STATUS` int(11) DEFAULT NULL, 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

而且我添加了一個唯一索引:

ALTER TABLE `IDM_USER_MEASURE` 
    ADD UNIQUE KEY unique_measure (`USER_ID`, `MEASURE_ID`, `MEASURE_DATE`); 

我現在做到以下幾點:

INSERT INTO `IDM_USER_MEASURE`(`USER_ID`, `MEASURE_ID`, `MEASURE_DATE`, `MEASURE_STATUS`) VALUES(1, 1, "bla", "status one"); 
INSERT INTO `IDM_USER_MEASURE`(`USER_ID`, `MEASURE_ID`, `MEASURE_DATE`, `MEASURE_STATUS`) VALUES(1, 1, "bla", "status updated"); 

這不起作用,因爲唯一的索引,但我想舊的行更新,使「狀態之一」成爲「狀態更新」。

如何在唯一索引發生衝突時自動更新我的行?

回答

1

僅限手動。

最接近你可以自動化這樣的事情將是一個觸發器;但那些不允許你在操作上的表(比該行其他觸發......類似INSERT的可選ON DUPLICATE KEY條款)

或者修改數據,你可以刪除嚴格的唯一性約束,而是有一個EVENT定期執行此操作。當然,這樣做的缺點是在每個時間間隔內,可能會累積非唯一的一組值。

另一種選擇是將INSERT限制在普通用戶的表中,而不是創建一個存儲過程(用適當的權限定義)來處理這些插入,在INSERT之前運行UPDATE。

編輯:哦,我明白了,問題是想要更新現有的行而不是插入,而不是更新現有的行,以便插入可以創建一個沒有違反唯一性的新行。

2

MySQL提供REPLACE INTO語句,如果違反約束,它將更新現有的行。

REPLACE作品酷似INSERT,不同之處在於,如果一個老行的表具有相同的值作爲一個PRIMARY KEY新行或UNIQUE指數,插入新行之前舊行被刪除。

REPLACE INTO `IDM_USER_MEASURE`(`USER_ID`, `MEASURE_ID`, `MEASURE_DATE`, `MEASURE_STATUS`) VALUES(1, 1, "bla", "status updated"); 

http://sqlfiddle.com/#!9/b0f6b/1

+2

謝謝您的回答。換成是粉碎索引不是嗎?我想我找到了一個很好的解決方案:'INSERT INTO'IDM_USER_MEASURE'('USER_ID','MEASURE_ID','MEASURE_DATE','MEASURE_STATUS')VALUES(1,1,「bla」,「status updated」)ON DUPLICATE KEY UPDATE MEASURE_STATUS = VALUES(MEASURE_STATUS);' – Mulgard

+0

是的,它是刪除然後插入。如果你有一個巨大的數據集,這並不好。 – miken32