PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Връщане на редове от INSERT с ON CONFLICT без необходимост от актуализиране

Това е повтарящият се проблем на SELECT or INSERT , свързан с (но различен от) UPSERT. Новата функционалност UPSERT в Postgres 9.5 все още е важна.

WITH ins AS (
   INSERT INTO names(name)
   VALUES ('bob')
   ON     CONFLICT ON CONSTRAINT names_name_key DO UPDATE
   SET    name = NULL
   WHERE  FALSE      -- never executed, but locks the row
   RETURNING id
   )
SELECT id FROM ins
UNION  ALL
SELECT id FROM names
WHERE  name = 'bob'  -- only executed if no INSERT
LIMIT  1;

По този начин всъщност не пишете нова версия на ред без нужда.

Въпреки това , все още има малък ъглов калъф за състояние на състезание . Едновременните транзакции може да са добавили конфликтен ред, който все още не се вижда в същото изявление. След това INSERT и SELECT излизат празни.

Правилно решение за едноредов UPSERT:

  • Изберете или INSERT във функция предразположени ли са условия на състезание?

Общи решения за групово UPSERT:

  • Как да използвам RETURNING с ON CONFLICT в PostgreSQL?

Без едновременно натоварване на запис

Ако едновременното записване (от друга сесия) не е възможно, не е необходимо да заключвате реда и можете да опростите:

WITH ins AS (
   INSERT INTO names(name)
   VALUES ('bob')
   ON     CONFLICT ON CONSTRAINT names_name_key DO NOTHING  -- no lock needed
   RETURNING id
   )
SELECT id FROM ins
UNION  ALL
SELECT id FROM names
WHERE  name = 'bob'  -- only executed if no INSERT
LIMIT  1;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Не може да се свърже с postgres от отдалечен хост

  2. Инсталиране на PostgreSQL на Docker

  3. LIKE заявка за елементи от плосък jsonb масив

  4. Интегриране на PostgreSQL със системи за удостоверяване

  5. MigrationSchemaMissing(Не може да се създаде таблицата django_migrations (%s) % exc)