Rumah >pangkalan data >tutorial mysql >Bagaimana untuk Mendapatkan Data Apabila Menggunakan PostgreSQL's ON CONFICT DO NOT APA-APA dengan RETURNING?

Bagaimana untuk Mendapatkan Data Apabila Menggunakan PostgreSQL's ON CONFICT DO NOT APA-APA dengan RETURNING?

Patricia Arquette
Patricia Arquetteasal
2025-01-21 18:36:08661semak imbas

How to Retrieve Data When Using PostgreSQL's ON CONFLICT DO NOTHING with 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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn