PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chèn dữ liệu vào 3 bảng cùng một lúc bằng Postgres

Sử dụng CTE sửa đổi dữ liệu :

WITH ins1 AS (
   INSERT INTO sample(firstname, lastname)
   VALUES ('fai55', 'shaggk')
-- ON     CONFLICT DO NOTHING         -- optional addition in Postgres 9.5+
   RETURNING id AS sample_id
   )
, ins2 AS (
   INSERT INTO sample1 (sample_id, adddetails)
   SELECT sample_id, 'ss' FROM ins1
   RETURNING user_id
   )
INSERT INTO sample2 (user_id, value)
SELECT user_id, 'ss2' FROM ins2;

Mỗi INSERT phụ thuộc vào cái trước. SELECT thay vì VALUES đảm bảo không có gì được chèn vào các bảng phụ nếu không có hàng nào được trả về từ INSERT trước đó . (Vì Postgres 9.5+, bạn có thể thêm ON CONFLICT .)
Theo cách này, nó cũng ngắn hơn và nhanh hơn một chút.

Thông thường, sẽ thuận tiện hơn khi cung cấp các hàng dữ liệu hoàn chỉnh ở một nơi :

WITH data(firstname, lastname, adddetails, value) AS (
   VALUES                              -- provide data here
      ('fai55', 'shaggk', 'ss', 'ss2') -- see below
    , ('fai56', 'XXaggk', 'xx', 'xx2') -- works for multiple input rows
       --  more?                      
   )
, ins1 AS (
   INSERT INTO sample (firstname, lastname)
   SELECT firstname, lastname          -- DISTINCT? see below
   FROM   data
   -- ON     CONFLICT DO NOTHING       -- UNIQUE constraint? see below
   RETURNING firstname, lastname, id AS sample_id
   )
, ins2 AS (
   INSERT INTO sample1 (sample_id, adddetails)
   SELECT ins1.sample_id, d.adddetails
   FROM   data d
   JOIN   ins1 USING (firstname, lastname)
   RETURNING sample_id, user_id
   )
INSERT INTO sample2 (user_id, value)
SELECT ins2.user_id, d.value
FROM   data d
JOIN   ins1 USING (firstname, lastname)
JOIN   ins2 USING (sample_id);

db <> fiddle here

Bạn có thể cần phôi loại rõ ràng trong một VALUES độc lập biểu thức - trái ngược với VALUES biểu thức được đính kèm với một INSERT nơi các kiểu dữ liệu được lấy từ bảng đích. Xem:

  • Truyền kiểu NULL khi cập nhật nhiều hàng

Nếu nhiều hàng có thể đi kèm với (firstname, lastname) , bạn có thể cần phải gấp các bản sao cho INSERT đầu tiên :

...
INSERT INTO sample (firstname, lastname)
SELECT DISTINCT firstname, lastname FROM data
...

Bạn có thể sử dụng bảng (tạm thời) làm nguồn dữ liệu thay vì CTE data .

Có lẽ sẽ hợp lý nếu kết hợp điều này với một ràng buộc DUY NHẤT trên (firstname, lastname) trong bảng và một ON CONFLICT mệnh đề trong truy vấn.

Có liên quan:

  • Cách sử dụng RETURNING với ON CONFLICT trong PostgreSQL?
  • CHỌN hoặc CHÈN trong một hàm có nguy cơ gặp phải các điều kiện về chủng tộc không?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. gem cài đặt pg không thể liên kết với libpq

  2. Lược đồ PostgreSQL / Không gian tên với Django

  3. Cốt lõi của Entity Framework - Chứa phân biệt chữ hoa chữ thường hay không phân biệt chữ hoa chữ thường?

  4. [Video] Tích hợp dữ liệu với PostgreSQL

  5. cú pháp khóa ngoại postgresql