Запрос Upsert не работает с нулевым значением.как обновить с нулевым значением в ограничениях? - PullRequest
0 голосов
/ 16 февраля 2019

Я использую pgsql upsert запрос на конфликт, основанный на комбинации из трех столбцов.Здесь один столбец может быть нулевым или нет, а два других столбца всегда будут содержать значение.Запрос Upsert работает (обновляет значения), когда все три столбца имеют значения, если другой столбец, который может иметь значение NULL, не имеет значений, поэтому он вставляет запись вместо обновления.

CREATE TABLE "public"."plan_line_items" (
    "plan_id" int4 NOT NULL
    "module_id" int4 NOT NULL,
    "sub_module_id" int4,
    "created_date" timestamptz(6) NOT NULL DEFAULT now(),
    "modified_date" timestamptz(6) NOT NULL DEFAULT now(),
    "created_by" int4 NOT NULL,
    "modified_by" int4 NOT NULL,
    "is_active" bool NOT NULL DEFAULT true,
);

INSERT INTO plan_line_items1 ( plan_id,module_id, sub_module_id, created_by, modified_by, modified_date )
VALUES ( '1', '1', '1', '36', '36', 'now()' ),
( '1', '2', null, '36', '36', 'now()' ) ON CONFLICT ( 
plan_id,module_id,sub_module_id ) DO UPDATE SET modified_by = EXCLUDED.modified_by,
modified_date = EXCLUDED.modified_date

Когда я попробовал этот запрос в первый разего вставка записи.после этого, когда я попробовал второй раз, он обновляет только ту запись, которая имеет все plan_id, module_id, sub_module_id с 1. не обновляет ту запись, которая уже вставлена ​​с третьим нулевым значением ('1', '2', null, '36 ',' 36 ',' now () ').Я перепробовал много вещей, но не нашел способа сделать это.Я хочу обновить эту запись при выполнении этого запроса во второй раз вместо вставки.Если у кого-нибудь есть решение, пожалуйста, помогите.

1 Ответ

0 голосов
/ 16 февраля 2019

Вы несколько неверно истолковываете, что означает NULL здесь в контексте вашего уникального ограничения (которое, как я полагаю, у вас есть, даже если оно отсутствует в вашем DDL).

sub_module_id сзначение NULL не означает «это plan_line_item не имеет sub_module_id», это означает «мы не знаем, имеет ли это plan_line_item sub_module_id».Вот почему он не работает должным образом в вашем уникальном ограничении.

Я бы предложил изменить тип данных столбца sub_module_id на:

sub_module_id int4 not null default 0

... и затем вставитьзначение 0 вместо NULL для тех plan_line_item строк, которые не имеют sub_module_id.Отсюда:

CREATE TABLE regt.plan_line_items (
    plan_id int4 NOT null,
    module_id int4 NOT NULL,
    sub_module_id int4 not null default 0,
    created_date timestamptz(6) NOT NULL DEFAULT now(),
    modified_date timestamptz(6) NOT NULL DEFAULT now(),
    created_by int4 NOT NULL,
    modified_by int4 NOT NULL,
    is_active bool NOT NULL DEFAULT true,
    unique (plan_id,module_id,sub_module_id)
);

INSERT INTO regt.plan_line_items ( plan_id,module_id, sub_module_id, created_by, modified_by, modified_date )
VALUES ( '1', '1', '1', '36', '36', 'now()' ),
( '1', '2', '0', '36', '36', 'now()' ) ON CONFLICT ( 
plan_id,module_id,sub_module_id ) DO UPDATE SET modified_by = EXCLUDED.modified_by,
modified_date = EXCLUDED.modified_date;

Или, иначе говоря: NULL! = NULL

...