Реализацията на UPSERT е изключително сложна, за да бъде безопасна срещу едновременен достъп до запис. Разгледайте този Postgres Wiki, който служи като лог по време на първоначалната разработка. Хакерите на Postgres решиха да не включват "изключени" редове в RETURNING
клауза за първата версия в Postgres 9.5. Може да изградят нещо за следващата версия.
Това е най-важното изявление в ръководството, за да обясните вашата ситуация:
Синтаксисът на
RETURNING
списъкът е идентичен с този на изходния списък наSELECT
. Ще бъдат върнати само редове, които са били успешно вмъкнати или актуализирани. Например, ако ред е бил заключен, но не е актуализиран, защотоON CONFLICT DO UPDATE ... WHERE
условието на клаузата не е изпълнено, редът няма да бъде върнат.
Удебелен акцент мое.
Заединичен ред за вмъкване:
Без едновременно натоварване при запис в една и съща таблица
WITH ins AS (
INSERT INTO users(name)
VALUES ('new_usr_name') -- input value
ON CONFLICT(name) DO NOTHING
RETURNING users.id
)
SELECT id FROM ins
UNION ALL
SELECT id FROM users -- 2nd SELECT never executed if INSERT successful
WHERE name = 'new_usr_name' -- input value a 2nd time
LIMIT 1;
С възможно едновременно натоварване на запис в таблицата
Помислете за това вместо това (за единичен ред INSERT
):
- Изберете или INSERT във функция предразположени ли са условия на състезание?
За да вмъкнете набор от редове :
-
Как да използвам RETURNING с ON CONFLICT в PostgreSQL?
-
Как да включите изключените редове в ВРЪЩАНЕ от INSERT ... ON CONFLICT
И трите с много подробно обяснение.