简体   繁体   English

INSERT ... ON CONFLICT DO UPDATE 中的不明确列引用

[英]Ambiguous column reference in INSERT … ON CONFLICT DO UPDATE

Given a table:给定一张桌子:

CREATE TABLE IF NOT EXISTS test."TestCounter" 
("id" TEXT PRIMARY KEY, 
 "count" INTEGER);

I'd like to insert a record and increment the counter if the record already exists如果记录已经存在,我想插入一条记录并增加计数器

INSERT INTO test."TestCounter" ("id")
VALUES ('id-0')
 ON CONFLICT ("id") DO UPDATE
 SET "count" = ("count" + 1)
 RETURNING "count"

Currently I get this error:目前我收到此错误:

ERROR:  column reference "count" is ambiguous
LINE 4:  SET "count" = "count" + 1
                       ^
SQL state: 42702
Character: 107

You need to table-qualify the column where it would be otherwise ambiguous.您需要对否则会模棱两可的列进行表格限定。
Use the virtual table name excluded to refer to the input row.使用excluded的虚拟表名称来引用输入行。 But you probably want to refer to the target column, so qualify with the name of the target table:但是您可能想要引用目标列,因此使用目标表的名称进行限定:

INSERT INTO test.test_counter (id)
VALUES ('id-0')
ON CONFLICT (id) DO UPDATE
SET count = test_counter.count + 1  -- here
RETURNING count;

The manual: 手册:

Note that the special excluded table is used to reference values originally proposed for insertion.请注意,特殊excluded表用于引用最初建议插入的值。

The single row from the virtual input table excluded contains all columns of the target table, even if not listed in the target column list of the INSERT or the VALUES expression. excluded的虚拟输入表中的单行包含目标表的所有列,即使未在INSERTVALUES表达式的目标列列表中列出。 So the ambiguity you encountered is always there, whether count is targeted explicitly or not.因此,您遇到的歧义始终存在,无论count是否明确定位。

Aside: Columns omitted in the target column list default to their respective column DEFAULT value, which is NULL by default ( NULL being the default column DEFAULT ).另外:目标列列表中省略的列默认为其各自的列DEFAULT值,默认为NULLNULL是默认列DEFAULT )。 Ie, it would default to NULL in your setup and 1 in my improved setup below.即,它在您的设置中默认为NULL ,在我下面的改进设置中默认为1 And row-level triggers BEFORE INSERT (if any) are applied.并应用BEFORE INSERT的行级触发器(如果有)。

But neither of that applies for the example as it refers to the target column after all.但这都不适用于该示例,因为它毕竟是指目标列。

Notably, the other two instances of the column name count are unambiguous (and thus do not require table-qualification) as those can only refer to the target table.值得注意的是,列名count的其他两个实例是明确的(因此不需要表限定),因为它们只能引用目标表。

Your setup can easily break while the column count isn't defined NOT NULL , as NULL + 1 is still NULL .当未定义列count NOT NULL时,您的设置很容易中断,因为NULL + 1仍然是NULL This setup would make more sense:这种设置会更有意义:

CREATE TABLE test.test_counter (
  id    text PRIMARY KEY
, count integer NOT NULL DEFAULT 1
);

Also not using quoted CaMeL-case names in my example.在我的示例中也没有使用引用的 CaMeL 案例名称。 See:看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM