问题描述
这是一个令人头疼的事情。
我在CONCAT
的上下文中使用ON DUPLICATE KEY UPDATE
,它吐出了非常奇怪的结果。
假设一个表存在两列三行,因此:
term | reference
0cm | 49-5;
10p | 890-1;
11s | 491-1;
16761 | 768-1;
(尽管有数字,但它们都是VARCHAR字符串。)
现在假设我们运行以下查询:
INSERT INTO dictionary (`term`,`references`)
VALUES
('0cm','35-6;'),('10p','89-12;'),('16761','491-7;')
ON DUPLICATE KEY UPDATE
`references` = CONCAT(`references`,`references` = CONCAT(`references`,'491-7;');
因为term
是唯一索引,所以ON DUPLICATE KEY
成为脚本的活动部分(保留不受影响的11s
)。预期的行为是我们的新值将被追加到现有值。
查询成功运行,但是给了我这些意外的结果:
term | reference
0cm | 49-5;35-6;89-12;491-7;
10p | 890-1;35-6;89-12;491-7;
11s | 491-1;
16761 | 768-1;35-6;89-12;491-7;
它已将{em> 的每个值reference
连接起来。
在reference
执行其ON DUPLICATE KEY
之前,有什么方法可以“清除” UPDATE
引用吗?
解决方法
INSERT INTO dictionary (`term`,`references`)
VALUES
('0cm','35-6;'),('10p','89-12;'),('16761','491-7;')
ON DUPLICATE KEY UPDATE
`references` = CASE term WHEN '0cm' THEN CONCAT(`references`,'35-6;')
WHEN '10p' THEN CONCAT(`references`,'89-12;')
WHEN '16761' THEN CONCAT(`references`,'491-7;')
END;
或者简单地
INSERT INTO dictionary (`term`,'491-7;')
ON DUPLICATE KEY UPDATE
`references` = CONCAT(`references`,VALUES(references));
,
如果没有重复键,请使用VALUES(references)
获取将要插入到该行中的值。
INSERT INTO dictionary (`term`,VALUES(`references`));
顺便说一句,您应该阅读以下内容:Is storing a delimited list in a database column really that bad?
,我怀疑您想要
INSERT INTO dictionary (term,references)
VALUES
('0cm','491-7;')
ON DUPLICATE KEY UPDATE
references = CONCAT_WS(';',references,VALUES(reference));
当给出重复的reference
时,此字段将附加到term
列中。请注意,concat_ws()
可以正确处理références
最初为null
的边缘情况。