在多个后续插入中使用 INSERT ... RETURNING 的返回值

Use returned value of INSERT ... RETURNING in multiple following inserts

我正在尝试在多个后续 INSERT 中使用由 INSERT ... RETURNING 语句返回的值。

假设我们有以下 tables:

CREATE TABLE hosts (host_id SERIAL, name CHARACTER VARYING(20));
CREATE TABLE interfaces (interface_id SERIAL, host_id INTEGER, name CHARACTER VARYING(10), iface_ip INET);
INSERT INTO hosts (name) VALUES ('Host A'),('Host B');

我想要的是在第一个table(主机)中插入一行,获取创建的host_id,然后在第二个table(接口)中插入多行具有给定值和第一个语句中的 host_id。

我找到了以下方法,使用 CTE 和 SELECT 静态值对我有用,但我很确定,这不是实现它的方法...

WITH temp_table AS (
INSERT INTO hosts (name) VALUES ('Host C') RETURNING host_id AS last_hostid
), i1 AS (
INSERT INTO interfaces (host_id, name, iface_ip) SELECT last_hostid, 'eth0', '192.168.1.1' FROM temp_table
), i2 AS (
INSERT INTO interfaces (host_id, name, iface_ip) SELECT last_hostid, 'eth1', '192.168.2.1' FROM temp_table
), i3 AS (
INSERT INTO interfaces (host_id, name, iface_ip) SELECT last_hostid, 'eth2', '192.168.3.1' FROM temp_table
) SELECT 1;

我知道我可以很容易地做到这一点,方法是用 PHP 与网络服务器对话,然后在下一个语句中填写变量。但我想在没有所有来回的情况下完成它,只在 PostgreSQL 中。所以,如果有比我更好的方法(我很确定)- 有什么提示吗?

您可以使用要插入的行创建一个 CTE,然后将其用作实际插入的源:

WITH temp_table AS (
  INSERT INTO hosts (name) VALUES ('Host C') 
  RETURNING host_id AS last_hostid
), new_data (name, iface_ip) AS (
  values 
    ('eth0', '192.168.1.1'::inet),
    ('eth1', '192.168.2.1'::inet),
    ('eth2', '192.168.3.1'::inet)
)
INSERT INTO interfaces (host_id, name, iface_ip) 
SELECT last_hostid, nd.name, nd.iface_ip
FROM new_data as nd, temp_table;

SELECT 中的(隐式)交叉连接并不重要,因为 temp_table 只有 return 一行。