sql >> Databasteknik >  >> RDS >> PostgreSQL

RETURNING orsakar fel:FROM-satspost saknas för tabellen

Det är sant, som har noterats, att RETURNING sats av en INSERT ser bara den infogade raden. Mer specifikt, citerar manualen här a> :

Fet betoning min.
Så inget hindrar dig från att lägga till en korrelerad underfråga till RETURNING lista:

INSERT INTO employees.password_resets AS ep
       (empl_pwd_reset_uuid                  , empl_user_pvt_uuid                    , t_valid                     , for_empl_user_pvt_uuid, token)
SELECT 'f70a0346-a077-11eb-bd1a-aaaaaaaaaaaa', '6efc2b7a-f27e-11ea-b66c-de1c405de048', '2021-04-18 19:57:47.111365', eu.empl_user_pvt_uuid , '19d65aea-7c4a-41bc-b580-9d047f1503e6'
FROM   employees.users eu
WHERE  empl_user_pub_uuid = 'e2bb39f1f28011eab66c63cb4d9c7a34'
RETURNING for_empl_user_pvt_uuid AS empl_user_pvt_uuid  -- alias to meet your org. query
        , (SELECT email
           FROM   employees.emails
           WHERE  empl_user_pvt_uuid = ep.empl_user_pvt_uuid
           ORDER  BY t DESC  -- NULLS LAST ?
           LIMIT  1
          ) AS email
        , (SELECT name_first
           FROM   employees.profiles
           WHERE  empl_user_pvt_uuid = ep.empl_user_pvt_uuid
           -- ORDER  BY ???
           LIMIT  1
          ) AS name_first;

Detta är också mycket effektivare än den fråga du hade (eller vad som föreslagits) av flera skäl.

Plus, kanske viktigast, detta är korrekt . Vi använder data från raden som faktiskt har infogats - efter sätter in den. (Se citat överst!) Efter möjliga standardvärden har triggers eller regler tillämpats. Vi kan vara säkra på att det vi ser är det som faktiskt finns i databasen (för närvarande).

Du har ingen ORDER BY för profiles.name_first . Det är inte rätt. Antingen finns det bara en kvalificerande rad, då behöver vi ingen DISTINCT inte heller LIMIT 1 . Eller så kan det vara flera, då behöver vi också en deterministisk ORDER BY för att få ett deterministiskt resultat.

Och om emails.t kan vara NULL, vill du lägga till NULLS LAST i ORDER BY klausul. Se:

Index

Helst har du dessa flerkolumnindex (med kolumner i denna ordning):

  • users (empl_user_pub_uuid, empl_user_pvt_uuid)
  • emails (empl_user_pvt_uuid, email)
  • profiles (empl_user_pvt_uuid, name_first)

Sedan, om borden är tillräckligt sugna, får du tre index-skanningar och hela operationen blir snabbare.

Hämta pre-INSERT värden?

Om du verkligen vill det (vilket jag inte tror att du gör), överväg:



  1. Välj kolumnvärde om inte null annars använd ett annat kolumnvärde

  2. Lägg upp MySQL-resultat med AJAX via jQuery

  3. Hur man exporterar och importerar befintlig användare (med dess privilegier!)

  4. Hur kan sortering av objekt i hinkar formuleras som ett giltigt JPQL-uttryck?