sql >> Databáze >  >> RDS >> PostgreSQL

RETURNING způsobí chybu:chybí záznam klauzule FROM pro tabulku

Je pravda, jak bylo uvedeno, že RETURNING klauzule INSERT vidí pouze vložený řádek. Přesněji řečeno, cituji manuál zde :

Tučné důraz můj.
Nic vám tedy nebrání přidat korelovaný poddotaz do RETURNING seznam:

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;

To je také mnohem efektivnější než dotaz, který jste měli (nebo to, co bylo navrženo) z několika důvodů.

Navíc, což je možná nejdůležitější, je to správné . Použijeme data z řádku, který byl skutečně vložen – po jeho vložení. (Viz citace nahoře!) Po použití možných výchozích hodnot, spouštěčů nebo pravidel. Můžeme si být jisti, že to, co vidíme, je to, co je skutečně v databázi (aktuálně).

Nemáte žádné ORDER BY pro profiles.name_first . To není správné. Buď je pouze jeden kvalifikační řádek, pak nepotřebujeme žádný DISTINCT ani LIMIT 1 . Nebo jich může být více, pak potřebujeme také deterministický ORDER BY získat deterministický výsledek.

A pokud emails.t může být NULL, budete chtít přidat NULLS LAST v ORDER BY doložka. Viz:

Indexy

V ideálním případě máte tyto vícesloupcové indexy (se sloupci v tomto pořadí):

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

Pokud jsou pak stoly dostatečně vysáté, získáte tři skenování pouze s indexem a celá operace se zrychlí.

Získejte před-INSERT hodnoty?

Pokud to opravdu chcete (což si nemyslím, že chcete), zvažte:



  1. Jak vytvořit uloženou proceduru v MySQL pomocí Knex raw

  2. Průběh celkem... s obratem

  3. Seznam úkolů

  4. Převést řetězec na blob java