我有一张桌子:
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"变为"状态更新"。
如何在唯一索引发生碰撞时自动更新行?
答案 0 :(得分: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");
答案 1 :(得分:1)
仅限手动。
最接近你可以自动化这样的事情将是一个触发器;但那些不允许你更改操作表中的数据(除了被触发的行...类似于INSERT
的可选ON DUPLICATE KEY
子句)
或者,您可以删除严格的唯一性约束,而是使用EVENT
定期执行此操作。当然,这样做的缺点是在每个间隔期间,可以累积非唯一的值集。
另一种选择是将INSERT限制为来自普通用户的表,而是创建一个存储过程(使用适当的权限定义)来处理这些插入,以便在INSERT之前运行UPDATE。
编辑:哦,我知道,问题想要更新现有行而不是插入,而不是更新现有行,因此插入可以创建一个没有唯一性违规的新行。