Tôi đang viết một công việc để chuyển đổi dữ liệu từ một thiết kế cũ sang một thiết kế mới. Trong quá trình này, tôi cần lấy id từ một tệp chèn vào một bảng riêng biệt và sử dụng mã đó trong một tệp chèn vào bảng đích, như sau:
CREATE TABLE t1 {
t1_id BIGSERIAL,
col1 VARCHAR
};
CREATE TABLE t2 {
t2_id BIGSERIAL,
col2 VARCHAR, -- renamed from col1 to avoid confusion
t1_id BIGINT REFERENCES t1.t1_id
};
Tôi có SQL được định nghĩa khớp với mẫu sau:
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, (SELECT * FROM ins)
FROM t3 a;
Tôi muốn điều này để chạy SELECT * FROM ins
cho mọi hàng của SELECT
.. nhưng thay vào đó, nó chỉ chạy một lần và sử dụng giá trị đó cho tất cả các hàng trong SELECT
. Làm cách nào tôi có thể cấu trúc lại SQL của mình để có được hành vi mong muốn?
chỉnh sửa4
t1 kết thúc giống như:
1,<NULL>
(1 row)
t2 kết thúc giống như:
10,'a',1
11,'b',1 -- problem with id from t1 being 1
12,'c',1 -- problem with id from t1 being 1
.
.
Những gì tôi muốn t1 trông giống như:
1,<NULL>
2,<NULL>
3,<NULL>
.
.
Những gì tôi muốn t2 trông giống như:
10,'a',1
11,'b',2 -- id from t1 of 2
12,'c',3 -- id from t1 of 3
.
.
chỉnh sửa Để giải quyết những gì a_horse_with_no_name đã nói, tôi cũng đã thử điều này (với kết quả tương tự):
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, b.t1_id
FROM t3 a
JOIN ins b ON TRUE;
edit2
Tôi vừa thử trực tiếp tham chiếu thích hợp SEQUENCE
trong truy vấn của mình và điều đó KHÔNG hoạt động - nhưng tôi hoàn toàn không thích giải pháp đó (chủ yếu là vì tôi không thích tên đối tượng mã hóa cứng.) Nếu có giải pháp nào khác hơn là trực tiếp tham khảo tên của SEQUENCE
tôi sẽ đánh giá cao nó. :)
chỉnh sửa3
Tôi cho rằng một giải pháp khác là sử dụng một PROCEDURE
để làm INSERT
thay vì CTE .. nhưng tôi vẫn đánh giá cao các tùy chọn / đề xuất.
t1
và không cung cấp bất kỳ giá trị nào cho t1.col1
. Dữ liệu nên đến đâu cho cột đó? Có t1.col1
liên quan đến t2.col1
?
INSERT INTO t1 (t1_id) VALUES (DEFAULT)
chỉ chèn 1 hàng vào t1
. Vì vậy, không có vấn đề gì nếu bạn đặt ins
trong FROM
mệnh đề và tham gia t3
hay không. Bạn có thể chỉ cho chúng tôi cách bạn sẽ chèn 2 (hoặc nhiều) hàng vào t1
không? Và quan trọng hơn, làm thế nào bạn biết t1.id
giá trị nào trong số 2 (hoặc nhiều hơn) sẽ được khớp với các hàng được chèn vào t2
?
ins
vàt3