Saya punya tabel tag
dengan 2 kolom: id
(uuid) dan name
(teks). Saya sekarang ingin memasukkan tag baru ke dalam tabel, tetapi jika tag sudah ada, saya hanya ingin mendapatkan id
catatan yang ada.
Saya berasumsi saya hanya bisa menggunakan ON CONFLICT DO NOTHING
dalam kombinasi dengan RETURNING "id"
:
INSERT INTO
"tag" ("name")
VALUES( 'foo' )
ON CONFLICT DO NOTHING
RETURNING "id";
Tapi ini mengembalikan set hasil kosong, jika tag dengan nama "foo" sudah ada.
Saya kemudian mengubah kueri untuk menggunakan DO UPDATE
klausa noop :
INSERT INTO
"tag" ("name")
VALUES( 'foo' )
ON CONFLICT ("name") DO UPDATE SET "name" = 'foo'
RETURNING "id";
Ini berfungsi sebagaimana dimaksud, tetapi agak membingungkan, karena saya hanya mengatur nama ke nilai yang sudah ada.
Apakah ini cara untuk mengatasi masalah ini atau apakah ada pendekatan yang lebih sederhana yang saya lewatkan?
postgresql
upsert
postgresql-9.5
Der Hochstapler
sumber
sumber
returning excluded.id
?ERROR: missing FROM-clause entry for table "excluded"
saat menggunakanDO NOTHING
.Jawaban:
Ini akan berfungsi (sejauh yang saya uji) dalam ketiga kasus, jika nilai yang akan dimasukkan semuanya baru atau semua sudah ada dalam tabel atau campuran:
Mungkin ada beberapa cara lain untuk melakukan ini, mungkin tanpa menggunakan
ON CONFLICT
sintaks baru .sumber
Tidak tahu apakah ini akan melakukan tetapi hanya sebagai pilihan lain untuk mencoba, di sini adalah melakukan cara sekolah yang lama (tanpa
ON CONFLICT
):Artinya, masukkan hanya nama [unik] yang tidak ditemukan dalam
tag
tabel dan kembalikan ID; menggabungkannya dengan ID dari nama-nama yang ada di sanatag
, untuk hasil akhir. Anda juga dapat melemparname
ke output, seperti yang disarankan oleh ypercubeᵀᴹ , sehingga Anda tahu ID mana yang cocok dengan nama yang mana.sumber
SELECT .. FROM ins UNION ALL SELECT ... FROM val JOIN tag ... ;