PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

RETURNING menyebabkan kesalahan:entri FROM-klausa tidak ada untuk tabel

Memang benar, seperti yang telah dicatat, bahwa RETURNING klausa dari INSERT hanya melihat baris yang disisipkan. Lebih khusus lagi, mengutip manual di sini :

Tebal penekanan saya.
Jadi tidak ada yang menghalangi Anda untuk menambahkan subkueri yang berkorelasi ke RETURNING daftar:

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;

Ini juga jauh lebih efisien daripada kueri yang Anda miliki (atau apa yang diusulkan) karena berbagai alasan.

Plus, mungkin yang paling penting, ini benar . Kami menggunakan data dari baris yang sebenarnya telah dimasukkan - setelah memasukkannya. (Lihat kutipan di atas!) Setelah kemungkinan nilai default, pemicu atau aturan diterapkan. Kita dapat yakin bahwa apa yang kita lihat adalah apa yang sebenarnya ada di database (saat ini).

Anda tidak memiliki ORDER BY untuk profiles.name_first . Itu tidak benar. Jika hanya ada satu baris kualifikasi, maka kita tidak memerlukan DISTINCT atau LIMIT 1 . Atau bisa banyak, maka kita juga membutuhkan ORDER BY deterministik untuk mendapatkan hasil deterministik.

Dan jika emails.t bisa NULL, Anda ingin menambahkan NULLS LAST di ORDER BY ayat. Lihat:

Indeks

Idealnya, Anda memiliki indeks multikolom ini (dengan kolom dalam urutan ini):

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

Kemudian, jika tabel cukup disedot, Anda mendapatkan tiga pemindaian indeks saja dan seluruh operasi menjadi lebih cepat.

Dapatkan pra-INSERT nilai?

Jika Anda benar-benar menginginkannya (yang menurut saya tidak), pertimbangkan:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL Penskalaan Vertikal

  2. Kelas Model JPA untuk bidang TIMESTAMP TANPA ZONA WAKTU DEFAULT CURRENT_TIMESTAMP di Postgres?

  3. Partisi Postgresql dan sqlalchemy

  4. Temukan nama host dan port menggunakan perintah PSQL

  5. Bagaimana cara membuat postgresSQL berfungsi di komputer windows 7 dengan Django?