使用一个 cte postgres 进行多次插入
Multiple inserts using one cte postgres
我是 postgres 的初学者。在做一个虚拟项目时,我遇到了这个问题。
我有两个表假设 t1 和 t2.The t1 与 t2 有 1-> 多关系。
我正在尝试编写一个 SQL 语句,它首先在 t1 中插入数据,然后使用 t1 中的 id 在 t2 中插入多行。
像这样。
WITH ins AS (
INSERT INTO t1(t1_col)
VALUES (4)
RETURNING t1_id
)
INSERT INTO t2(t1_id, t2_col) VALUES (ins.t1_id, 3), (ins.t1_id, 4)...
t1 结构 -> (t1_id primary_key 串行,t1_col 整数).
t2 结构 -> (t2_id primary_key 串行,t1_id 整数,t2_col 整数).
正确的做法是什么。
提前致谢。
一个匿名的 plpgsql 块就可以了。
do language plpgsql
$$
declare
t1id t1.t1_id%type;
begin
INSERT INTO t1(t1_col) VALUES (4) RETURNING t1_id INTO t1id;
INSERT INTO t2(t1_id, t2_col)
VALUES (t1id, 3), (t1id, 4)...;
end;
$$;
除了使用 VALUES
子句插入外,您可以插入 SELECT
的结果。一般形式为:
WITH ins AS (
INSERT INTO table1(target columns)
VALUES (some values) -- or -- SELECT something FROM somewhere
RETURNING some_id
)
INSERT INTO table2(target columns)
SELECT ins.some_id, other columns or expressions
FROM ins;
多行的变体(固定列表)
WITH ins AS (
INSERT INTO table1(target columns)
VALUES (some values) -- or -- SELECT something FROM somewhere
RETURNING some_id
)
INSERT INTO table2(target columns)
SELECT ins.some_id, UNNEST(ARRAY[3,4,...])
FROM ins;
其中 3,4.... 是值列表
这将在一条语句中完成。
WITH ins AS (
INSERT INTO t1(t1_col)
VALUES (4)
RETURNING t1_id
)
INSERT INTO t2(t1_id, t2_col)
SELECT ins.t1_id, v.t2_col
from ins
cross join (VALUES (3), (4)) as v(t2_col)
;
如果您运行来自宿主语言并且可以将 t2
值作为数组传递,请发表评论,因为这可以简化。
我会像这样构建它以用于宿主语言:
with invars as (
select as t1_col, ::text[] as t2_cols
), ins as (
insert into t1 (t1_col)
select t1_col
from invars
returning t1_id
)
insert into t2 (t1_id, t2_col)
select ins.t1_id, unnest(invars.t2_cols) as t2_col
from ins
cross join invars;
然后,我将从主机传递 t1_col
和一组 t2_col
值作为查询的参数。
无需 CTE 或变量,您可以使用 lastval()
获取最后生成的标识(或序列)值:
INSERT INTO t1(t1_col)
VALUES (4);
INSERT INTO t2(t1_id, t2_col)
VALUES
(lastval(), 3),
(lastval(), 4),
...
我是 postgres 的初学者。在做一个虚拟项目时,我遇到了这个问题。
我有两个表假设 t1 和 t2.The t1 与 t2 有 1-> 多关系。
我正在尝试编写一个 SQL 语句,它首先在 t1 中插入数据,然后使用 t1 中的 id 在 t2 中插入多行。
像这样。
WITH ins AS (
INSERT INTO t1(t1_col)
VALUES (4)
RETURNING t1_id
)
INSERT INTO t2(t1_id, t2_col) VALUES (ins.t1_id, 3), (ins.t1_id, 4)...
t1 结构 -> (t1_id primary_key 串行,t1_col 整数).
t2 结构 -> (t2_id primary_key 串行,t1_id 整数,t2_col 整数).
正确的做法是什么。
提前致谢。
一个匿名的 plpgsql 块就可以了。
do language plpgsql
$$
declare
t1id t1.t1_id%type;
begin
INSERT INTO t1(t1_col) VALUES (4) RETURNING t1_id INTO t1id;
INSERT INTO t2(t1_id, t2_col)
VALUES (t1id, 3), (t1id, 4)...;
end;
$$;
除了使用 VALUES
子句插入外,您可以插入 SELECT
的结果。一般形式为:
WITH ins AS (
INSERT INTO table1(target columns)
VALUES (some values) -- or -- SELECT something FROM somewhere
RETURNING some_id
)
INSERT INTO table2(target columns)
SELECT ins.some_id, other columns or expressions
FROM ins;
多行的变体(固定列表)
WITH ins AS (
INSERT INTO table1(target columns)
VALUES (some values) -- or -- SELECT something FROM somewhere
RETURNING some_id
)
INSERT INTO table2(target columns)
SELECT ins.some_id, UNNEST(ARRAY[3,4,...])
FROM ins;
其中 3,4.... 是值列表
这将在一条语句中完成。
WITH ins AS (
INSERT INTO t1(t1_col)
VALUES (4)
RETURNING t1_id
)
INSERT INTO t2(t1_id, t2_col)
SELECT ins.t1_id, v.t2_col
from ins
cross join (VALUES (3), (4)) as v(t2_col)
;
如果您运行来自宿主语言并且可以将 t2
值作为数组传递,请发表评论,因为这可以简化。
我会像这样构建它以用于宿主语言:
with invars as (
select as t1_col, ::text[] as t2_cols
), ins as (
insert into t1 (t1_col)
select t1_col
from invars
returning t1_id
)
insert into t2 (t1_id, t2_col)
select ins.t1_id, unnest(invars.t2_cols) as t2_col
from ins
cross join invars;
然后,我将从主机传递 t1_col
和一组 t2_col
值作为查询的参数。
无需 CTE 或变量,您可以使用 lastval()
获取最后生成的标识(或序列)值:
INSERT INTO t1(t1_col)
VALUES (4);
INSERT INTO t2(t1_id, t2_col)
VALUES
(lastval(), 3),
(lastval(), 4),
...