Rumah >pangkalan data >tutorial mysql >Bagaimana untuk Mendapatkan Data Apabila Menggunakan PostgreSQL's ON CONFICT DO NOT APA-APA dengan RETURNING?
PostgreSQL ON CONFLICT DO NOTHING
dan Pengambilan Data
Apabila menggunakan klausa ON CONFLICT DO NOTHING
PostgreSQL dengan RETURNING
, hasil kosong dikembalikan apabila konflik berlaku. Ini kerana DO NOTHING
tidak mengemas kini atau mengembalikan sebarang baris. Artikel ini meneroka penyelesaian untuk mendapatkan semula data walaupun konflik timbul.
Cabaran dan Had Pendekatan Sedia Ada
Kaedah sedia ada sering menangani perkara ini untuk sasaran konflik tunggal dan keadaan mudah. Walau bagaimanapun, pendekatan ini boleh mempunyai had dan potensi kesan sampingan.
Penyelesaian Teguh untuk Mendapatkan Data
Kami membentangkan dua pendekatan yang dipertingkatkan untuk mengendalikan konflik dengan berkesan dan memastikan pengambilan data, menangani senario penulisan serentak:
1. Mengendalikan Konflik Tanpa Tulisan Serentak
Kaedah ini menggunakan Common Table Expression (CTE) untuk memisahkan operasi INSERT
dan SELECT
. Hasilnya digabungkan menggunakan UNION ALL
.
<code class="language-sql">WITH input_rows(usr, contact, name) AS ( VALUES ('foo1', 'bar1', 'bob1') , ('foo2', 'bar2', 'bob2') -- more? ) , ins AS ( INSERT INTO chats (usr, contact, name) SELECT * FROM input_rows ON CONFLICT (usr, contact) DO NOTHING RETURNING id ) SELECT 'i' AS source, id FROM ins UNION ALL SELECT 's' AS source, c.id FROM input_rows JOIN chats c USING (usr, contact);</code>
Pertanyaan ini mula-mula cuba memasukkan. Kemudian, ia memilih baris sedia ada yang sepadan dengan data input. Lajur source
menunjukkan sama ada baris telah disisipkan ('i') atau dipilih ('s').
2. Mengendalikan Konflik Dengan Tulisan Serentak
Penyelesaian yang lebih mantap ini menyumbang kepada operasi tulis serentak. Ia menyemak baris yang tiada dalam pertanyaan dan menggunakan UPSERT
tambahan untuk mengendalikannya.
<code class="language-sql">WITH input_rows(usr, contact, name) AS ( ... ) -- as above , ins AS ( INSERT INTO chats (usr, contact, name) SELECT * FROM input_rows ON CONFLICT (usr, contact) DO NOTHING RETURNING id, usr, contact ) , sel AS ( SELECT 'i' AS source, id, usr, contact FROM ins UNION ALL SELECT 's' AS source, c.id, usr, contact FROM input_rows JOIN chats c USING (usr, contact) ) , ups AS ( INSERT INTO chats (usr, contact, name) SELECT i.* FROM input_rows i LEFT JOIN sel s USING (usr, contact) WHERE s.usr IS NULL ON CONFLICT (usr, contact) DO UPDATE SET name = c.name -- or EXCLUDED.name RETURNING 'u' AS source, id ) SELECT source, id FROM sel UNION ALL SELECT * FROM ups;</code>
Pendekatan ini memastikan semua baris yang dimasukkan atau dikemas kini dikembalikan, tanpa mengira konflik atau kemas kini serentak. ups
CTE mengendalikan mana-mana baris yang terlepas dalam INSERT
awal. Lajur source
membezakan antara baris yang disisipkan ('i'), yang dipilih ('s') dan ('u') yang dikemas kini. Ini menyediakan penyelesaian yang komprehensif untuk mendapatkan semula data dalam pelbagai keadaan.
Atas ialah kandungan terperinci Bagaimana untuk Mendapatkan Data Apabila Menggunakan PostgreSQL's ON CONFICT DO NOT APA-APA dengan RETURNING?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!