PostgreSQL ON CONFLICT DO UPDATE with not null column and COALESCE EXCLUDED column
PostgreSQL ON CONFLICT DO UPDATE with not null column and COALESCE EXCLUDED column
我想对可能包含 not null
约束违规但不引发错误的数据执行 UPSERT。我希望跳过建议的行而不是错误。
架构:
Table "public.appointments"
Column | Type | Modifiers
-------------+-----------------------------+--------------
id | bigint | not null
location_id | bigint | not null
time | timestamp without time zone | not null
status | text | not null
Indexes:
"appointments_pkey" PRIMARY KEY, btree (id)
"for_upsert" UNIQUE CONSTRAINT, btree (id, location_id)
现有记录:
id | location_id | status | time
----+-------------+--------+----------------------
1 | 2 | sched | 2017-12-15 01:10:00
2 | 2 | sched | 2017-12-19 01:30:00
查询:
INSERT INTO "objects" ("id", "location_id", "time")
VALUES (1, 2, 'sched', '2017-10-31 19:25:00'),
(2, 2, 'canc', NULL),
(3, 2, 'canc', NULL)
ON CONFLICT ON CONSTRAINT for_upsert DO UPDATE
SET "time" = COALESCE(EXCLUDED."time", "objects"."time"),
"status" = EXCLUDED."status"
当存在 time
不为空的记录时,我希望更新 status
而不管 EXCLUDED."time"
值(这就是 COALESCE 试图做的)。但是,如果没有现有记录并且新提议的行具有空 time
我不希望插入该行或引发错误。
添加此子句:
WHERE COALESCE(EXCLUDED."time", "appointments"."time") IS NOT NULL;
在 DO UPDATE SET...
似乎工作之后。
我想对可能包含 not null
约束违规但不引发错误的数据执行 UPSERT。我希望跳过建议的行而不是错误。
架构:
Table "public.appointments"
Column | Type | Modifiers
-------------+-----------------------------+--------------
id | bigint | not null
location_id | bigint | not null
time | timestamp without time zone | not null
status | text | not null
Indexes:
"appointments_pkey" PRIMARY KEY, btree (id)
"for_upsert" UNIQUE CONSTRAINT, btree (id, location_id)
现有记录:
id | location_id | status | time
----+-------------+--------+----------------------
1 | 2 | sched | 2017-12-15 01:10:00
2 | 2 | sched | 2017-12-19 01:30:00
查询:
INSERT INTO "objects" ("id", "location_id", "time")
VALUES (1, 2, 'sched', '2017-10-31 19:25:00'),
(2, 2, 'canc', NULL),
(3, 2, 'canc', NULL)
ON CONFLICT ON CONSTRAINT for_upsert DO UPDATE
SET "time" = COALESCE(EXCLUDED."time", "objects"."time"),
"status" = EXCLUDED."status"
当存在 time
不为空的记录时,我希望更新 status
而不管 EXCLUDED."time"
值(这就是 COALESCE 试图做的)。但是,如果没有现有记录并且新提议的行具有空 time
我不希望插入该行或引发错误。
添加此子句:
WHERE COALESCE(EXCLUDED."time", "appointments"."time") IS NOT NULL;
在 DO UPDATE SET...
似乎工作之后。