我在此表MySQL中设置唯一的索引类型时遇到问题。
在表格doTable
中,我在MyUniqueKey
上设置了一个唯一的索引类型,其字段为EventDate
和TES
。
我希望当EventDate
和TES
已经执行时,插入查询不会被执行。
DROP TABLE IF EXISTS `doTable`;
CREATE TABLE `doTable` (
`EventDate` date DEFAULT NULL,
`TES` varchar(4) DEFAULT NULL,
`Dicl` int(11) DEFAULT NULL,
`AVHS` int(11) DEFAULT NULL,
`ID` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ID`),
UNIQUE KEY `MyUniqueKey` (`EventDate`,`TES`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
我需要在doTable
的旧行doTable_old
中插入并尝试此代码:
INSERT IGNORE INTO `doTable` (
`EventDate`,
`TES`,
`Dicl`,
`AVHS`
) SELECT
`EventDate`,
`TES`,
SUM(`Dicl`),
SUM(`AVHS`)
FROM
`doTable_old`
WHERE
`EventDate` = '2015-02-05'
`TES` = 'M201';
当EventDate
和TES
已经存在时,插入查询不会在doTable
中执行。
现在我需要使用新算法更新Dicl
上的字段doTable
的值,我尝试过这样做:
UPDATE IGNORE `doTable` A
JOIN (
SELECT
SUM(tmp0.`Dicl`) AS `Dicl`
FROM
`doTable_cons` tmp
JOIN `doTable_old` tmp0 ON tmp0.Codes = tmp.Codes
WHERE
`TES` = 'M201'
AND `EventDate` = '2015-02-05'
GROUP BY
`EventDate`
ORDER BY
`EventDate` ASC
) AS x
SET A.`Dicl` = A.`Dicl` + x.`Dicl`
WHERE
A.`TES` = x.`TES`;
相反,在这种情况下,即使Dicl
和doTable
已经在EventDate
上,TES
上的字段doTable
的值也会始终更新。
我的意思是,如果我在第一次更新+2时使用旧的第10行,则新值为12,如果我再次尝试更新值14然后是16然后18 ......应该保持在12。 ..但关键是不起作用......
我错过了什么?
此代码有什么问题?
提前谢谢。
答案 0 :(得分:0)
当您更改唯一键中使用的字段时,重复键才会发挥作用,导致发生重复违规,或者您插入的新记录会导致违规。
使用第二个查询时,您不会更改唯一键中使用的EITHER字段。因此,更新将继续,因为没有发生违规。
e.g。
表X(唯一键(x,y))
x y z
1 1 0
1 2 0
INSERT (x,y) VALUES (1,1) // fails - would create a dupe violation
INSERT (x,Y) VALUES (1,3) // succeeds - no dupe
UPDATE ... SET y=2 WHERE x=1 AND y=1 // fails - would create a dupe
UPDATE ... SET z=z+1 where x=1 AND y=1 // no problem, no dupe
换句话说,根据您的逻辑,更新数据库中的任何记录都是不可能的,因为表上的任何更改都会导致欺骗密钥违规。这显然是完全错误的。