PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zwróć identyfikator, jeśli wiersz istnieje, WSTAW W przeciwnym razie

Rozwiązanie w jednej instrukcji SQL. Wymaga PostgreSQL 8.4 lub później.
Rozważ następującą prezentację:

Konfiguracja testowa:

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');

WSTAW / WYBIERZ polecenie:

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;
  • Pierwsze CTE v nie jest bezwzględnie konieczne, ale osiąga, że ​​musisz wprowadzić swoje wartości tylko raz.

  • Drugi wybór CTE id z tbl jeśli „wiersz” istnieje.

  • Trzecie wstawia CTE i "wiersz" do tbl jeśli (i tylko jeśli) nie istnieje, zwracając id .

  • Ostatni SELECT zwraca id . Dodałem kolumnę src wskazując "źródło" - czy "wiersz" istniał wcześniej i id pochodzi z SELECT lub „wiersz” był nowy, podobnie jak id .

  • Ta wersja powinna być tak szybka, jak to możliwe, ponieważ nie wymaga dodatkowego SELECT z tbl i zamiast tego używa CTE.

Aby zabezpieczyć to przed możliwymi warunkami wyścigu w środowisku wielu użytkowników:
Również dla zaktualizowanych technik przy użyciu nowego UPSERT w Postgres 9.5 lub później:

  • Czy SELECT lub INSERT w funkcji podatnej na wyścigi?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sortowanie drzewa ze zmaterializowaną ścieżką?

  2. Kompromisy we wdrożeniach w trybie gorącej gotowości

  3. Dopasuj frazę kończącą się prefiksem za pomocą wyszukiwania pełnotekstowego

  4. Twórz wiele instancji Postgres na tym samym komputerze

  5. Importuj pliki XML do PostgreSQL