Postgresql способ вставить строку с семантикой предложения "ON CONFLICT" - PullRequest
3 голосов
/ 03 мая 2011

Есть ли в Postgres простой способ сделать следующее в sqlite?

INSERT INTO foo (x, y, z) VALUES (1, 2, 3) ON CONFLICT replace;

Я осмотрелся и нашел решения, которые представляют собой сложные пользовательские функции. Другое решение моей проблемы - просто сделать

delete from foo where x=1; INSERT INTO foo (x, y, z) VALUES (1, 2, 3) ON CONFLICT replace;

, который не является семантически эквивалентным, но работает для моего случая.

Я бы предпочел правило ON CONFLICT, если оно не требует пользовательских функций.

Ответы [ 2 ]

3 голосов
/ 04 мая 2011

Начиная с версии 9.1 PostgreSQL (бета-версия на данный момент), вы можете использовать общее табличное выражение для вставки или замены:

/**
CREATE TABLE foo(id serial primary key, content text unique);
**/

WITH replace AS (
    DELETE FROM foo
    WHERE
        content = 'bar'
    RETURNING content
)
INSERT INTO 
    foo(content) -- values:
SELECT
    *
FROM replace RIGHT JOIN (SELECT CAST('bar' AS text) as content) sub USING(content);

'bar' isзначение, которое будет вставлено или заменено.

В старых версиях не работает, вам придется подождать: - (

2 голосов
/ 15 января 2016

Начиная с версии 9.5, PostgreSQL обеспечивает функциональность "UPSERT".

http://www.postgresql.org/docs/current/static/sql-insert.html

Обратите внимание на ON ON CONFLICT в команде Synopsis

...