好吧,标题可能看起来有点奇怪,但这就是我的情况。 我正在使用最新版本的 PostgreSQL。
我有一个模式叫做
schema_ex
我有 3 个表叫
A B C
表 A 有一个在插入时自动分配的唯一 ID(序列号)
id
我要插入40条记录
前 22
- 表 A 的 22 条记录,包含 3 列的 3 个值:NULL、'1'、1..22
- 表 B 中的 22,包含从上一个插入的表 A 返回的 2 列的 2 个值:id,1..22
- 对于我在表 A 中插入的每条记录,表 C 中有 5 条记录,其中包含第一次插入时从表 A 返回的 2 列的 2 个值:id,1..22
下一个 18
- 表 A 中的 18 条记录,包含 3 列的 3 个值:NULL、'2'、23..40
- 表 B 中的 18 个,包含从上一个插入的表 A 返回的 2 列的 2 个值:id,23..40
- 对于我在表 A 中插入的每条记录,表 C 中有 5 条记录,其中包含第一次插入时从表 A 返回的 2 列的 2 个值:id,23..40
41..N ...
- (为了方便而删减)
到目前为止我的代码是这样的
SET schema 'schema_ex';
DO
$do$
BEGIN
FOR j IN 1..22 LOOP
WITH i1 AS (
INSERT INTO A (col_a, col_b, col_c) VALUES (NULL, '2', j) RETURNING id, col_c
)
, i2 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i3 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i4 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i5 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i6 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
INSERT INTO B (id, col_c)
SELECT id, col_c FROM i1;
END LOOP;
END
$do$;
DO
$do$
BEGIN
FOR j IN 23..40 LOOP
WITH i1 AS (
INSERT INTO A (col_a, col_b, col_c) VALUES (NULL, '2', j) RETURNING id, col_c
)
, i2 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i3 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i4 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i5 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
, i6 AS (
INSERT INTO C (id, col_c)
SELECT id, col_c FROM i1
)
INSERT INTO B (id, col_c)
SELECT id, col_c FROM i1;
END LOOP;
END
$do$;
可以用但是不够优雅,所以我做了一个函数
CREATE OR REPLACE FUNCTION test.tmp()
RETURNS text AS
$BODY$
DECLARE
rec tmp_table%ROWTYPE;
BEGIN
FOR i IN 1..22 LOOP
WITH last AS (
INSERT INTO schema_ex.A (col_a, col_b, col_c)
VALUES (NULL, '1', i) RETURNING id, col_c
)
INSERT INTO tmp_table
SELECT id, col_c FROM last;
END LOOP;
FOR i IN 23..40 LOOP
WITH last AS (
INSERT INTO schema_ex.A (col_a, col_b, col_c)
VALUES (NULL, '2', i) RETURNING id, col_c
)
INSERT INTO tmp_table
SELECT id, col_c FROM last;
END LOOP;
FOR rec IN EXECUTE('SELECT * FROM tmp_table') LOOP
INSERT INTO schema_ex.B (id, col_c)
VALUES (rec.id, rec.col_c);
FOR j IN 1..5 LOOP
INSERT INTO schema_ex.C (text_id, col_c)
VALUES (rec.id, rec.col_c);
END LOOP;
END LOOP;
RETURN 'ok';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
但即使它有效,我也觉得它有点奇怪,有什么简单/优雅的方法可以满足我的需求吗?
最佳答案
据我所知有没有专门的功能
with last as (
insert into schema_ex.A select null, '1', i from generate_series( 1, 22 ) as i returning id, col_c;
)
仅作为示例。
这对你有用吗?
关于sql - 在多个表上插入的更好方法,从 SQL WITH 语句返回多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35591035/