8 postgresql array set-returning-functions bulk-insert
我已经看到了使用此示例进行批量插入的好方法:
WITH p AS (
INSERT INTO parent_table (column_1)
SELECT $1
RETURNING id)
INSERT INTO child_table (parent_table_id, column_a)
SELECT p.id, a
FROM p, unnest($2::text[]) AS a
Run Code Online (Sandbox Code Playgroud)
但是,我需要从多个数组中插入多行,所以我尝试了以下语法:
WITH p AS (
INSERT INTO parent_table (column_1)
SELECT $1
RETURNING id)
INSERT INTO child_table (parent_table_id, column_a, column_b)
SELECT p.id, a, b
FROM p, unnest($2::text[]) AS a, unnest($3::bigint[]) AS b
Run Code Online (Sandbox Code Playgroud)
我在parent_table_idand上有一个主键column_a,当我尝试执行此查询时,Postgres 抱怨重复键冲突。
应该如何解开数组以便它们形成单独的行?
换句话说,如果$2和$3都有两个条目,那么第一个条目如何$2只插入第一个条目,$3并且对于各自的第二个条目都相同?
如果这是不可能的,我可以构造一个多维数组吗?如果是这样,它应该如何与多种数组类型一起传递,多维数组语法是什么?
Erw*_*ter 12
这会做你想要的:
WITH p AS (
INSERT INTO parent_table (column_1)
SELECT $1
RETURNING id)
INSERT INTO child_table (parent_table_id, column_a, column_b)
SELECT p.id, t.a, t.b
FROM p, (SELECT unnest($2::text[]) AS a, unnest($3::bigint[]) AS b) t
Run Code Online (Sandbox Code Playgroud)
这里的微妙差别的是,unnest()在相同的调用SELECT列表中嵌套的并行如果要素的数量是相同的。但要小心:在 Postgres 9.6 或更早版本中,如果数字不相同,则会生成笛卡尔积。该行为在Postgres 10 中进行了消毒。看:
您可以使用更简洁的形式 withgenerate_subscripts()或其他技术,但这些会更加冗长。此相关问题中的详细信息:
WITH ORDINALITYPostgres 9.4 中的新功能允许使用更简洁(并且只是稍微冗长)的形式:
WITH p AS (...)
INSERT INTO child_table (...)
SELECT p.id, ta.a, tb.b
FROM p
, unnest($2::text[]) WITH ORDINALITY AS ta(a, rn)
JOIN unnest($3::bigint[]) WITH ORDINALITY AS tb(b, rn) USING (rn);
Run Code Online (Sandbox Code Playgroud)
使用接受多个数组的新形式,这种特殊情况甚至可以更简单unnest():
WITH p AS (...)
INSERT INTO child_table (...)
SELECT p.id, t.a, t.b
FROM p, unnest($2::text[], $3::bigint[]) AS t(a, b);
Run Code Online (Sandbox Code Playgroud)
此相关答案中的示例。
| 归档时间: |
|
| 查看次数: |
22108 次 |
| 最近记录: |