在INSERT...ON DUPLICATE KEY UPDATE的VALUES部分引用现有行字段值的方法
问题解答
不能在INSERT ... ON DUPLICATE KEY UPDATE语句的VALUES部分直接引用目标表已存在行的字段值,这就是你执行语句后字段被置空的原因——INSERT阶段数据库还未关联到已存在的行,直接引用myTable.Col2会返回NULL。
原因说明
INSERT的VALUES子句负责定义待插入的新数据,此时还未触发ON DUPLICATE KEY UPDATE的分支逻辑,数据库不会去查询目标表中已存在的行来提供字段值,所以这种引用方式没有有效上下文,结果只能是NULL。
针对你的需求的正确写法
要实现“当满足条件时保留原字段值,否则用新值”的逻辑,必须把IF判断放到ON DUPLICATE KEY UPDATE部分,因为只有在这个阶段,数据库才能访问到已存在的行数据。
场景1:条件基于插入的Col1值
INSERT INTO myTable (Col1, Col2) VALUES ('value', ?), ('value2', ?) ON DUPLICATE KEY UPDATE -- 当插入的Col1是'test'时,保留原Col2值,否则用插入的Col2值 Col2 = IF(VALUES(Col1) = 'test', myTable.Col2, VALUES(Col2)), -- 同步更新Col1为插入的值(如果需要) Col1 = VALUES(Col1);
场景2:条件是独立的预编译参数
如果你的第一个?是独立的条件参数,第二个?是新值,写法如下:
INSERT INTO myTable (Col1, Col2) VALUES ('value', ?), ('value2', ?) ON DUPLICATE KEY UPDATE -- 当条件参数等于'test'时,保留原Col2值,否则用插入的Col2值 Col2 = IF(? = 'test', myTable.Col2, VALUES(Col2)), Col1 = VALUES(Col1);
额外建议:业务场景适配
因为你的业务中所有行都已存在,也可以直接使用UPDATE语句,逻辑会更直观:
UPDATE myTable SET Col1 = CASE WHEN Col1 = 'value' THEN 'value' WHEN Col1 = 'value2' THEN 'value2' ELSE Col1 END, Col2 = IF(? = 'test', Col2, ?) WHERE Col1 IN ('value', 'value2');
内容的提问来源于stack exchange,提问作者Hasley
相关产品推荐
相关产品推荐

