PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Ottieni l'ID da un INSERT condizionale

L'implementazione di UPSERT è estremamente complessa per essere protetta dall'accesso simultaneo in scrittura. Dai un'occhiata a questo Wiki di Postgres che è servito da registro durante lo sviluppo iniziale. Gli hacker di Postgres hanno deciso di non includere le righe "escluse" nel RETURNING clausola per il primo rilascio in Postgres 9.5. Potrebbero creare qualcosa per la prossima versione.

Questa è l'affermazione cruciale nel manuale per spiegare la tua situazione:

La sintassi del RETURNING list è identico a quello dell'outputlist di SELECT . Verranno restituite solo le righe che sono state inserite o aggiornate correttamente. Ad esempio, se una riga è stata bloccata ma non aggiornata perché un ON CONFLICT DO UPDATE ... WHERE la condizione della clausola non è stata soddisfatta, la riga non verrà restituita.

Enfasi in grassetto la mia.

Per una riga singola per inserire:

Senza carico di scrittura simultaneo sulla stessa tabella

WITH ins AS (
   INSERT INTO users(name)
   VALUES ('new_usr_name')         -- input value
   ON     CONFLICT(name) DO NOTHING
   RETURNING users.id
   )
SELECT id FROM ins
UNION  ALL
SELECT id FROM users          -- 2nd SELECT never executed if INSERT successful
WHERE  name = 'new_usr_name'  -- input value a 2nd time
LIMIT  1;

Con possibile carico di scrittura simultaneo sulla tabella

Considera questo invece (per riga singola INSERT ):

  • SELEZIONA o INSERT in una funzione soggetta a condizioni di gara?

Per inserire un insieme di righe :

  • Come utilizzare RETURNING con ON CONFLICT in PostgreSQL?

  • Come includere le righe escluse in RETURNING from INSERT ... ON CONFLICT

Tutti e tre con una spiegazione molto dettagliata.