sql >> Databasteknik >  >> RDS >> PostgreSQL

Få ID från en villkorlig INSERT

UPSERT-implementeringen är enormt komplex för att vara säker mot samtidig skrivåtkomst. Ta en titt på denna Postgres Wiki som fungerade som logg under den initiala utvecklingen. Postgres hackare beslutade att inte inkludera "uteslutna" rader i RETURNING klausul för den första utgåvan i Postgres 9.5. De kanske bygger in något för nästa utgåva.

Detta är det avgörande uttalandet i manualen för att förklara din situation:

Syntaxen för RETURNING listan är identisk med den för utdatalistan för SELECT . Endast rader som har infogats eller uppdaterats kommer att returneras. Till exempel, om en rad var låst men inte uppdaterad eftersom en ON CONFLICT DO UPDATE ... WHERE klausulens villkor var inte uppfyllt, raden kommer inte att returneras.

Djärv betoning min.

För en en rad att infoga:

Utan samtidig skrivbelastning på samma tabell

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;

Med möjlig samtidig skrivbelastning på tabellen

Överväg detta istället (för en rad INSERT ):

  • Är SELECT eller INSERT i en funktion utsatt för tävlingsförhållanden?

För att infoga en uppsättning rader :

  • Hur använder man RETURNING med ON CONFLICT i PostgreSQL?

  • Hur man inkluderar exkluderade rader i RETURNING from INSERT ... ON CONFLICT

Alla tre med mycket detaljerad förklaring.



  1. Generera DDL programmatiskt på Postgresql

  2. PostgreSQL IN-operator med underfrågan dålig prestanda

  3. SQL-fel:ORA-01861:literal matchar inte formatsträngen 01861

  4. Hur tvingar man fram pascal-fall med Oracles Entity Framework-stöd?