INSERT 中不明确的列引用 ... ON CONFLICT DO UPDATE
Ambiguous column reference in INSERT ... ON CONFLICT DO UPDATE
给定一个 table:
CREATE TABLE IF NOT EXISTS test."TestCounter"
("id" TEXT PRIMARY KEY,
"count" INTEGER);
如果记录已经存在,我想插入一条记录并增加计数器
INSERT INTO test."TestCounter" ("id")
VALUES ('id-0')
ON CONFLICT ("id") DO UPDATE
SET "count" = ("count" + 1)
RETURNING "count"
目前我收到这个错误:
ERROR: column reference "count" is ambiguous
LINE 4: SET "count" = "count" + 1
^
SQL state: 42702
Character: 107
您需要 table 限定列,否则会产生歧义。
使用虚拟 table 名称 excluded
来引用输入行。但是您可能想引用目标列,所以用目标的名称限定 table:
INSERT INTO test.test_counter (id)
VALUES ('id-0')
ON CONFLICT (id) DO UPDATE
SET count = test_counter.count + 1 -- here
RETURNING count;
Note that the special excluded
table is used to reference values originally proposed for insertion.
来自虚拟输入 table excluded
的单行包含目标 table 的 所有 列,即使未在INSERT
或 VALUES
表达式的目标列列表。所以你遇到的歧义总是存在的,不管count
是不是明确针对
旁白:目标列列表中省略的列默认为其各自的列 DEFAULT
值,默认为 NULL
(NULL
是默认列 DEFAULT
).也就是说,在您的设置中它将默认为 NULL
,在我下面改进的设置中默认为 1
。并应用行级触发器 BEFORE INSERT
(如果有)。
但这两者都不适用于示例,因为它毕竟指的是 target 列。
值得注意的是,列名 count
的其他两个实例是明确的(因此不需要 table 限定),因为它们只能引用 目标 table.
当列 count
未定义 NOT NULL
时,您的设置很容易中断,因为 NULL + 1
仍然是 NULL
。这种设置会更有意义:
CREATE TABLE test.test_counter (
id text PRIMARY KEY
, count integer NOT NULL DEFAULT 1
);
在我的示例中也没有使用引用的 CaMeL 大小写名称。参见:
- Are PostgreSQL column names case-sensitive?
给定一个 table:
CREATE TABLE IF NOT EXISTS test."TestCounter"
("id" TEXT PRIMARY KEY,
"count" INTEGER);
如果记录已经存在,我想插入一条记录并增加计数器
INSERT INTO test."TestCounter" ("id")
VALUES ('id-0')
ON CONFLICT ("id") DO UPDATE
SET "count" = ("count" + 1)
RETURNING "count"
目前我收到这个错误:
ERROR: column reference "count" is ambiguous
LINE 4: SET "count" = "count" + 1
^
SQL state: 42702
Character: 107
您需要 table 限定列,否则会产生歧义。
使用虚拟 table 名称 excluded
来引用输入行。但是您可能想引用目标列,所以用目标的名称限定 table:
INSERT INTO test.test_counter (id)
VALUES ('id-0')
ON CONFLICT (id) DO UPDATE
SET count = test_counter.count + 1 -- here
RETURNING count;
Note that the special
excluded
table is used to reference values originally proposed for insertion.
来自虚拟输入 table excluded
的单行包含目标 table 的 所有 列,即使未在INSERT
或 VALUES
表达式的目标列列表。所以你遇到的歧义总是存在的,不管count
是不是明确针对
旁白:目标列列表中省略的列默认为其各自的列 DEFAULT
值,默认为 NULL
(NULL
是默认列 DEFAULT
).也就是说,在您的设置中它将默认为 NULL
,在我下面改进的设置中默认为 1
。并应用行级触发器 BEFORE INSERT
(如果有)。
但这两者都不适用于示例,因为它毕竟指的是 target 列。
值得注意的是,列名 count
的其他两个实例是明确的(因此不需要 table 限定),因为它们只能引用 目标 table.
当列 count
未定义 NOT NULL
时,您的设置很容易中断,因为 NULL + 1
仍然是 NULL
。这种设置会更有意义:
CREATE TABLE test.test_counter (
id text PRIMARY KEY
, count integer NOT NULL DEFAULT 1
);
在我的示例中也没有使用引用的 CaMeL 大小写名称。参见:
- Are PostgreSQL column names case-sensitive?