【发布时间】:2023-02-05 05:09:59
【问题描述】:
例子:
CREATE TABLE IF NOT EXISTS test
(
type character varying,
id integer
);
CREATE UNIQUE INDEX IF NOT EXISTS uniq_id_test
ON test USING btree (type, id)
WHERE (type = 'Test');
PREPARE test (text, int, text) AS
INSERT INTO test (type, id)
VALUES ($1, $2)
ON CONFLICT (type, id)
WHERE type = $3 DO
UPDATE
SET id = EXCLUDED.id;
EXECUTE test('Test', 1, 'Test');
EXECUTE test('Test', 2, 'Test');
EXECUTE test('Test', 3, 'Test');
EXECUTE test('Test', 4, 'Test');
EXECUTE test('Test', 5, 'Test');
EXECUTE test('Test', 6, 'Test');
最后一个 EXECUTE 语句总是抛出一个错误:
[42P10] 错误:没有匹配 ON CONFLICT 规范的唯一或排除约束
如果我们
DEALLOCATE准备好的语句然后重新创建它,我们将有另外 5 次成功尝试,并且在第 6 次尝试时我们将再次出现上述错误。如果我们用常量值
'Test'替换$3参数(没有错误),所有这些都可以正常工作:PREPARE test (text, int, text) AS INSERT INTO test (type, id) VALUES ($1, $2) ON CONFLICT (type, id) WHERE type = 'Test' DO UPDATE SET id = EXCLUDED.id;因此,据此,我可以假设根本原因是我在
INSERT ON CONFLICT WHERE准备语句中使用了参数而不是常量,并且 plancacher 或 smth 无法正确使用它。但我希望看到对上述问题的更详细解释,因为我不是数据库专家,也不明白为什么它会以这种方式工作......PG版本:
PostgreSQL 13.9 (Debian 13.9-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
【问题讨论】:
标签: sql postgresql sql-insert