具有 2 个唯一约束的 Postgres upsert
Postgres upsert with 2 unique constraints
我有一个带有 2 个唯一索引的 table 以允许其中一列中的空值。
CREATE TABLE public.pairs_dup
(
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
base integer NOT NULL,
quote integer NOT NULL,
delivery_date timestamp with time zone,
data float,
CONSTRAINT pairs_dup_pkey PRIMARY KEY (id)
)
CREATE UNIQUE INDEX pairs_dup_not_null_idx
ON public.pairs_dup USING btree
(base ASC NULLS LAST, quote ASC NULLS LAST, delivery_date ASC NULLS LAST)
WHERE delivery_date IS NOT NULL;
CREATE UNIQUE INDEX pairs_dup_null_idx
ON public.pairs_dup USING btree
(base ASC NULLS LAST, quote ASC NULLS LAST)
WHERE delivery_date IS NULL;
A) 我可以在提供 delivery_date 时执行更新插入吗?
INSERT INTO pairs_dup(base, quote, delivery_date, data) values ('A', 'B', '2016-06-22 19:10:25-07', 0.5)
ON CONFLICT (base, quote, delivery_date) DO UPDATE SET data = 0.5;
B) 我可以在不提供交货日期的情况下执行更新插入吗?
INSERT INTO pairs_dup(base, quote, data) values ('A', 'B', 0.5)
ON CONFLICT (base, quote, delivery_date) DO UPDATE SET data = 0.5;
Ad A): 是的,但是 ON CONFLICT
子句需要包含索引谓词:
INSERT INTO pairs_dup(base, quote, delivery_date, data)
VALUES (42, 4711, '2016-06-22 19:10:25-07', 0.5)
ON CONFLICT (base, quote, delivery_date)
WHERE delivery_date IS NOT NULL /* this is essential */
DO UPDATE SET data = 0.5;
正如the documentation所说:
<em><strong>index_predicate</strong></em>
Used to allow inference of partial unique indexes. Any indexes that satisfy the predicate (which need not actually be partial indexes) can be inferred.
广告 B):同样,您必须将 WHERE delivery_date IS NULL
添加到 ON CONFLICT
子句。
添加这些子句似乎是多余的,但这是必需的,以便可以推断出部分索引。
我有一个带有 2 个唯一索引的 table 以允许其中一列中的空值。
CREATE TABLE public.pairs_dup
(
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
base integer NOT NULL,
quote integer NOT NULL,
delivery_date timestamp with time zone,
data float,
CONSTRAINT pairs_dup_pkey PRIMARY KEY (id)
)
CREATE UNIQUE INDEX pairs_dup_not_null_idx
ON public.pairs_dup USING btree
(base ASC NULLS LAST, quote ASC NULLS LAST, delivery_date ASC NULLS LAST)
WHERE delivery_date IS NOT NULL;
CREATE UNIQUE INDEX pairs_dup_null_idx
ON public.pairs_dup USING btree
(base ASC NULLS LAST, quote ASC NULLS LAST)
WHERE delivery_date IS NULL;
A) 我可以在提供 delivery_date 时执行更新插入吗?
INSERT INTO pairs_dup(base, quote, delivery_date, data) values ('A', 'B', '2016-06-22 19:10:25-07', 0.5)
ON CONFLICT (base, quote, delivery_date) DO UPDATE SET data = 0.5;
B) 我可以在不提供交货日期的情况下执行更新插入吗?
INSERT INTO pairs_dup(base, quote, data) values ('A', 'B', 0.5)
ON CONFLICT (base, quote, delivery_date) DO UPDATE SET data = 0.5;
Ad A): 是的,但是 ON CONFLICT
子句需要包含索引谓词:
INSERT INTO pairs_dup(base, quote, delivery_date, data)
VALUES (42, 4711, '2016-06-22 19:10:25-07', 0.5)
ON CONFLICT (base, quote, delivery_date)
WHERE delivery_date IS NOT NULL /* this is essential */
DO UPDATE SET data = 0.5;
正如the documentation所说:
<em><strong>index_predicate</strong></em>
Used to allow inference of partial unique indexes. Any indexes that satisfy the predicate (which need not actually be partial indexes) can be inferred.
广告 B):同样,您必须将 WHERE delivery_date IS NULL
添加到 ON CONFLICT
子句。
添加这些子句似乎是多余的,但这是必需的,以便可以推断出部分索引。