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

Върнете идентификатора, ако съществува ред, INSERT в противен случай

Решение в един SQL израз. Изисква PostgreSQL 8.4 или по-късно обаче.
Помислете за следната демонстрация:

Тестова настройка:

CREATE TEMP TABLE tbl (
  id  serial PRIMARY KEY
 ,txt text   UNIQUE   -- obviously there is unique column (or set of columns)
);

INSERT INTO tbl(txt) VALUES ('one'), ('two');

Команда INSERT / SELECT:

WITH v AS (SELECT 'three'::text AS txt)
    ,s AS (SELECT id FROM tbl JOIN v USING (txt))
    ,i AS (
       INSERT INTO tbl (txt)
       SELECT txt
       FROM   v
       WHERE  NOT EXISTS (SELECT * FROM s)
       RETURNING id
       )
SELECT id, 'i'::text AS src FROM i
UNION  ALL
SELECT id, 's' FROM s;
  • ПървиятCTE v не е строго необходимо, но постига това, че трябва да въведете своите стойности само веднъж.

  • Вторият CTE s избира id от tbl ако "редът" съществува.

  • Третият CTE i вложки "реда" в tbl ако (и само ако) не съществува, връщайки id .

  • Крайният SELECT връща id . Добавих колона src посочване на "източника" - дали "редът" е съществувал преди и id идва от SELECT или "редът" е нов, както и id .

  • Тази версия трябва да е възможно най-бърза, тъй като не се нуждае от допълнителен SELECT от tbl и вместо това използва CTEs.

За да направите това безопасно срещу възможни условия на състезание в среда с множество потребители:
Също така за актуализирани техники, използващи новия UPSERT в Postgres 9.5 или по-късно:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Инсталиране на PostgreSQL в Ubuntu за Ruby on Rails

  2. Как да групирате по месеци в PostgreSQL

  3. Как да променя стила на дата в PostgreSQL?

  4. foreach %dopar% + RPostgreSQL

  5. Използване на pyspark за свързване с PostgreSQL