sql - 在多个表上插入的更好方法,从 SQL WITH 语句返回多个值

标签 sql postgresql

好吧,标题可能看起来有点奇怪,但这就是我的情况。 我正在使用最新版本的 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/

相关文章:

sql - UNION 子查询的奇怪行为,为什么?

sql - 如何在 SQL 中选择 XML Path 查询的输出?

c# - 日期范围查询的 SQL/ Entity Framework 错误

mysql - Laravel 获取分配给我的用户的订单(具有分配历史记录)

ruby-on-rails - 删除生产数据库 Capistrano 和 PostgreSQL || rails 5

sql - 按时间段聚合 SQL 列值

sql - PostgreSQL:NOT IN 与 EXCEPT 性能差异(编辑 #2)

具有许多左连接的 Postgresql 查询优化

ruby-on-rails - Rails Heroku 应用程序错误

node.js - 为什么我通过 App Engine 部署的应用无法连接到 Cloud SQL postgres 数据库?