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?