Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Postgres 9.5:"INSERT INTO ... ON CONFLICT" - Как понять произошла вставка или обновление?  [new]
shaposh
Member

Откуда: Москва
Сообщений: 158
Postgres 9.5
Как в конструкции
   INSERT INTO table (Id, Name)
        VALUES (:in_Id, :in_Name)
   ON CONFLICT (Id)
            DO             
        UPDATE 
           SET name = :in_name


понять какая операция была выполнена - вставка или обновление?

В Firebird в аналогичной конструкции "UPDATE OR INSERT" это достигается так:
   UPDATE OR INSERT INTO table (Id, Name) VALUES (:in_Id, :in_Name) RETURNING OLD.Id


т.е можно указать префикс перед возвращаемым PK: если он NULL, то произошла вставка...

А как получить информацию о том была вставка или обновление в Postgres?
15 июл 16, 12:17    [19413763]     Ответить | Цитировать Сообщить модератору
 Re: Postgres 9.5:"INSERT INTO ... ON CONFLICT" - Как понять произошла вставка или обновление?  [new]
shaposh
Member

Откуда: Москва
Сообщений: 158
Сорри, в Firebird конечно же так:
UPDATE OR INSERT INTO table (Id, Name)
          VALUES (:in_Id, :in_Name)
        MATCHING (Id)
       RETURNING OLD.Id
15 июл 16, 12:32    [19413846]     Ответить | Цитировать Сообщить модератору
 Re: Postgres 9.5:"INSERT INTO ... ON CONFLICT" - Как понять произошла вставка или обновление?  [new]
grufos
Member

Откуда: Москва
Сообщений: 102
shaposh,

можно решить эту проблему путём использования системной невидимой колонки xmax
https://www.postgresql.org/docs/9.5/static/ddl-system-columns.html
https://postgrespro.ru/docs/postgrespro/9.5/ddl-system-columns.html

тест
CREATE TABLE account
(
  id bigserial,
  name varchar,
  surname varchar,
  address varchar,
  PRIMARY KEY (id),
  CONSTRAINT unique_person UNIQUE (name, surname, address)
);

INSERT INTO account as a (id, name, surname, address)
VALUES (1, 'Вася', 'Пупкин', 'Москва, Кремль')
ON CONFLICT (id)
DO UPDATE SET
name=EXCLUDED.name || ' (бывший ' || a.name || ')',
surname=EXCLUDED.surname || ' (бывший ' || a.surname || ')'
returning xmax, * ;

xmax	id	name	surname	address
0	1	Вася	Пупкин	Москва, Кремль

INSERT INTO account AS a (id, name, surname, address)
VALUES (1, 'Петя', 'Петров', 'Москва, Кремль')
ON CONFLICT (id)
DO UPDATE SET
name=EXCLUDED.name || ' (бывший ' || a.name || ')',
surname=EXCLUDED.surname || ' (бывший ' || a.surname || ')'
returning xmax, * ;

xmax	       id	name	                        surname	                        address
22087375	1	Петя (бывший Вася)	Петров (бывший Пупкин)	Москва, Кремль


т.е.
0 - выполнена вставка
не 0 - выполнен update
19 июл 16, 14:51    [19427458]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить