PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Kembalikan id jika ada baris, MASUKKAN sebaliknya

Solusi dalam satu pernyataan SQL. Memerlukan PostgreSQL 8.4 atau lebih baru.
Pertimbangkan demo berikut:

Penyiapan pengujian:

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

Perintah 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 pertama tidak sepenuhnya diperlukan, tetapi untuk mencapainya Anda harus memasukkan nilai hanya sekali.

  • Pilihan CTE kedua id dari tbl jika "baris" itu ada.

  • CTE ketiga yang saya masukkan "baris" menjadi tbl jika (dan hanya jika) tidak ada, kembalikan id .

  • SELECT final terakhir mengembalikan id . Saya menambahkan kolom src menunjukkan "sumber" - apakah "baris" sudah ada sebelumnya dan id berasal dari SELECT, atau "baris" baru dan begitu juga id .

  • Versi ini harus secepat mungkin karena tidak memerlukan SELECT tambahan dari tbl dan menggunakan CTE sebagai gantinya.

Untuk membuat ini aman dari kemungkinan kondisi balapan di lingkungan multi-pengguna:
Juga untuk teknik yang diperbarui menggunakan UPSERT baru di Postgres 9.5 atau lebih baru:

  • Apakah SELECT atau INSERT dalam fungsi rentan terhadap kondisi balapan?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tambahkan Bulan ke Tanggal di PostgreSQL

  2. PostgreSQL:Bagaimana cara mengatur search_path di tingkat pengguna?

  3. daftar postgresql dan pesan tabel berdasarkan ukuran

  4. Menggunakan psql bagaimana cara membuat daftar ekstensi yang diinstal dalam database?

  5. Django, mod_wsgi, psycopg2 ImproperlyConfigured:Kesalahan memuat modul psycopg2:Tidak ada modul bernama _psycopg