Postgres 9.4 - Как игнорировать дубликат ключа при вставке строк в таблицу - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть таблица story_id, как это.

    Column    |  Type   |                             Modifiers
--------------+---------+-------------------------------------------------------------------
 id           | integer | not null default nextval('story_sites_id_seq'::regclass)
 story_id     | integer | not null
 site_id      | integer | not null

Я хочу добавить новые строки с site_id = 12 и story_id, которые уже имеют site_id = 70, вот мой запрос, он работает хорошо:

INSERT INTO story_sites (story_id, site_id)
SELECT story_id, 12
FROM story_sites
WHERE site_id = 70;

Но еслиесть строки, в которых уже есть site_id = 12, я получу ошибку дублирующего ключа.

Итак, я хочу исключить эти дублирующиеся строки, вот мой новый запрос, однако он не работает должным образом, онничего не вставляет, когда я думаю, что это должно.Также кажется, что я не могу использовать ON CONFLICT DO NOTHING в Postgres 9.4.Как мне это сделать?

INSERT INTO story_sites (story_id, site_id)
SELECT story_id, 12
FROM story_sites
WHERE site_id = 70
AND NOT EXISTS
(
    SELECT id
    FROM story_sites
    WHERE site_id = 12
);

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

Перейти с версии 9.4 на 9.5. Не выполнять подзапросов .Это может привести к снижению производительности . С Postgres 9.5 вы можете просто использовать:

INSERT INTO my_table (id, name) VALUES (1, 'Me') 
ON CONFLICT DO NOTHING;
0 голосов
/ 07 декабря 2018

Вы рядом.Вам просто нужно принять во внимание story_id:

INSERT INTO story_sites (story_id, site_id)
    SELECT ss.story_id, 12
    FROM story_sites ss
    WHERE ss.site_id = 70 AND
          NOT EXISTS (SELECT id
                      FROM story_sites ss2
                      WHERE ss2.site_id = 12 AND ss2.sotry_id = ss.story_id
                     );

Все это говорит о том, что этот запрос все еще может иметь проблемы, если несколько вставок происходят одновременно.То, что вы действительно должны использовать, это on conflict do nothing, что объясняется в документации для insert.

...