Ton*_*ali 27 postgresql upsert postgresql-9.5
鉴于:
CREATE TABLE A (
PK_A INT8 NOT NULL,
A INT8,
PRIMARY KEY (PK_A)
);
CREATE TABLE B (
PK_B INT8 NOT NULL,
B INT8,
PRIMARY KEY (PK_B)
);
Run Code Online (Sandbox Code Playgroud)
这个查询:
insert into table_b (pk_b, b)
select pk_a,a from table_a
on conflict (b) do update set b=a;
Run Code Online (Sandbox Code Playgroud)
导致以下错误:
Run Code Online (Sandbox Code Playgroud)ERROR: column "a" does not exist LINE 1: ...elect pk_a,a from table_a on conflict (b) do update set b=a; ^ HINT: There is a column named "a" in table "*SELECT*", but it cannot be referenced from this part of the query.
如何在参考内容的同时进行更新table_a?
Erw*_*ter 42
多个问题。
您的设置,扩展:
CREATE TABLE a (
pk_a int PRIMARY KEY
, a int
, comment text -- added column to make effect clear
);
CREATE TABLE b (
pk_b int PRIMARY KEY
, b int
, comment text
);
INSERT INTO a VALUES (1, 11, 'comment from a')
, (2, 22, 'comment from a');
INSERT INTO b VALUES (1, 77, 'comment from b');
Run Code Online (Sandbox Code Playgroud)
这有效:
INSERT INTO b (pk_b, b, comment)
SELECT pk_a, a, comment
FROM a
ON CONFLICT (pk_b) DO UPDATE -- conflict is on the unique column
SET b = excluded.b; -- key word "excluded", refer to target column
Run Code Online (Sandbox Code Playgroud)
结果:
TABLE b;
pk_b | b | comment
------+----+----------------
1 | 11 | comment from b -- updated
2 | 22 | comment from a -- inserted
Run Code Online (Sandbox Code Playgroud)
你感到困惑table_a,并A在您的演示(如@Abelisto评论)。
使用合法的、小写的、不带引号的标识符有助于避免混淆。
就像提到的@Ziggy一样,ON CONFLICT仅适用于实际的唯一或排除约束违规。手册:
可选
ON CONFLICT子句指定了引发唯一违规或排除约束违规错误的替代操作。
因此,不能工作,那里没有约束。ON CONFLICT (b)ON CONFLICT (pk_b)作品。
就像@Ziggy 也提到的一样,源表名称在该UPDATE部分中不可见。手册:
中的
SETandWHERE子句ON CONFLICT DO UPDATE可以使用表名(或别名)访问现有行,并 使用特殊excludedtable 访问建议插入的行。
大胆强调我的。
您也不能在部件中使用源表的列名UPDATE。它必须是目标行的列名。所以你真的想要:
SET b = excluded.b
Run Code Online (Sandbox Code Playgroud)
请注意,所有每行
BEFORE INSERT触发器的影响都反映在排除值中,因为这些影响可能导致行被排除在插入之外。
Eze*_*nay 10
在 PostgreSQL 9.5+ 中执行更新插入时,您必须通过 alias 引用排除的数据(插入失败的数据)excluded。此外,该on conflict选项必须引用 key:(pk_b)而不是(b)。例如。
insert into table_b (pk_b, b)
select pk_a,a from table_a
on conflict (pk_b) do update set b=excluded.b;
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅官方文档或upsert 的简单介绍。
| 归档时间: |
|
| 查看次数: |
76788 次 |
| 最近记录: |