为何SELECT语句结合INSERT ON CONFLICT执行Upsert会报错?
SELECT方式执行Upsert报错,VALUES方式却正常?
我编写了如下SQL语句:
INSERT INTO names (first, last) SELECT first, last FROM tmp ON CONFLICT(first) DO UPDATE SET seen = seen + 1;
执行时出现错误:
Parse error near line 11: near "DO": syntax error
但如果手动指定VALUES插入数据,相同的ON CONFLICT逻辑却能正常运行:
INSERT INTO names (first, last) VALUES ('Bob', 'Smith') ON CONFLICT(first) DO UPDATE SET seen = seen + 1;
问题原因与解决方法
问题出在语法位置错误:ON CONFLICT是INSERT语句的专属子句,必须紧跟在数据来源(不管是VALUES还是SELECT)之后,不能被当成SELECT语句的一部分。你之前的写法把ON CONFLICT放在了FROM tmp后面,数据库会尝试将其解析为SELECT语句的组成部分,自然无法识别DO关键字,因此抛出语法错误。
修正后的SQL语句如下:
INSERT INTO names (first, last) SELECT first, last FROM tmp ON CONFLICT(first) DO UPDATE SET seen = seen + 1;
不管用VALUES还是SELECT作为INSERT的数据来源,Upsert的语法规则是统一的:ON CONFLICT必须作为整个INSERT语句的最后组成部分,不能嵌套在SELECT子句中。调整位置后,就能正常执行Upsert操作了。
内容的提问来源于stack exchange,提问作者Random Data Monster
相关产品推荐
相关产品推荐

