gpt4 book ai didi

sql - ON CONFLICT DO UPDATE 缺少 FROM 子句

转载 作者:行者123 更新时间:2023-11-29 11:20:39 24 4
gpt4 key购买 nike

我有一个简单的表(id 和名称列,都是唯一的),我正在导入一个制表符分隔的 CSV 文件。

我正在运行 psql 9.5,并且想尝试新的 ON CONFLICT 功能来在 ID 已经存在的情况下更新名称列。

CREATE TEMP TABLE tmp_x AS SELECT * FROM repos LIMIT 0;
COPY tmp_x FROM '/Users/George/git-parser/repo_file' (format csv, delimiter E'\t');
INSERT INTO repos SELECT * FROM tmp_x
ON CONFLICT(name) DO UPDATE SET name = tmp_x.name;
DROP TABLE tmp_x;

我收到这个错误:

SELECT 0
COPY 1
ERROR: missing FROM-clause entry for table "tmp_x"
LINE 4: ON CONFLICT(name) DO UPDATE SET name = tmp_x.name;
^
Query failed
PostgreSQL said: missing FROM-clause entry for table "tmp_x"

不太确定这里出了什么问题。

最佳答案

如果你看the documentation of the ON CONFLICT clause ,它说的是关于“冲突行动”:

The SET and WHERE clauses in ON CONFLICT DO UPDATE have access to the existing row using the table's name (or an alias)

在您的查询中,目标表是repos

另一方面,

tmp_x 是您尝试插入的数据源,但 ON CONFLICT 子句无法“看到”- 它正在寻找在已计算但失败的特定行。想想你是否写过这样的东西:

INSERT INTO repos SELECT max(foo_id) FROM tmp_x

显然,无法将未能插入到 repos 中的行访问 tmp_x 中的任何一行。

如果无法查看被拒绝的数据,整个功能将毫无用处,但如果我们继续阅读:

... and to rows proposed for insertion using the special excluded table.

因此,您需要访问魔术表别名 excluded,它包含您尝试插入但发生冲突的值,给您:

INSERT INTO repos SELECT * FROM tmp_x
ON CONFLICT(name) DO UPDATE SET name = excluded.name;

如果为此目的弹出一个虚构的表名看起来很奇怪,请考虑在编写触发器时发生类似的事情,你会得到 OLDNEW(取决于关于你正在编写的那种触发器)。

关于sql - ON CONFLICT DO UPDATE 缺少 FROM 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35159431/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com