我想在Postgres的表中插入多个(2)行,并将插入中WITH ROWS AS
返回的ID用于另一个表(列id_1
和id_2
在second_table
)中,并将 id作为查询的最终结果返回。
first_table
是主要的数据集合,second_table
基本上只将两个first_table
条目链接在一起。
以下是我要做的事情的要点:
WITH row AS (
INSERT INTO first_table (some_data, more_data)
VALUES (DEFAULT, DEFAULT), (DEFAULT, DEFAULT)
RETURNING first_table_id
)
INSERT INTO second_table (id_1, id_2, other_data)
VALUES (???, ???, DEFAULT)
RETURNING second_table_id
我正在使用Node.js和node-pg
模块;我知道这可以在Node.js中完成,方法是让第一个查询返回WITH ROWS AS
返回的两行,然后使用两个id为下一个插入运行另一个预准备语句。
我不确定我是否可以通过触发器执行此操作,因为ON INSERT
只有一行。也许它会有两个,因为这些行在同一个事务中插入first_table
,但我对Postgres / SQL一般没有丰富的经验,所以我不知道如何通过触发器来做到这一点。 / p>
我遇到的问题是WITH ROWS AS
语句返回2行(显然是有意),但我无法弄清楚如何在下一个插入中独立访问每一行,我有一种感觉这是不可能的。
这可以在单个查询中完成,还是我 使用触发器或Node.js?
答案 0 :(得分:3)
第二个插入需要是INSERT INTO ... SELECT ... FROM first_cte
。如果你可以做出一个假设,那么第二个生成的id大于第一个(或者至少是不同的和可比较的 - 如果你使用PostgreSQL的serial
或者直接使用序列就是这种情况),你可以使用聚合:
WITH rows AS (
INSERT INTO first_table (some_data, more_data)
VALUES (DEFAULT, DEFAULT), (DEFAULT, DEFAULT)
RETURNING first_table_id
)
INSERT INTO second_table (id_1, id_2)
SELECT min(first_table_id), max(first_table_id)
FROM rows
RETURNING second_table_id
请注意,other_data
被省略:您无法使用DEFAULT
中的INSERT INTO ... SELECT ...
。
对于更通用的解决方案,您可以使用数组:
WITH rows AS (
INSERT INTO first_table (some_data, more_data)
VALUES (DEFAULT, DEFAULT), (DEFAULT, DEFAULT)
RETURNING first_table_id
)
INSERT INTO second_table (id_1, id_2, other_data)
SELECT first_table_ids[1], first_table_ids[2], 5 -- value '5' for "other_data"
FROM (
SELECT array_agg(first_table_id) AS first_table_ids
FROM rows
) AS rows_as_array
RETURNING second_table_id