Использовать возвращаемое значение INSERT ... RETURNING в нескольких следующих вставках - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь использовать значение, возвращаемое оператором INSERT ... RETURNING в нескольких следующих INSERT.

Допустим, у нас есть следующие таблицы:

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');

Что я хочу, это вставить строку в первую таблицу (hosts), получить созданный host_id, а затем вставить несколько строк во вторую таблицу (интерфейсы) с заданными значениями и 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.Итак, если есть лучший способ, чем мой (и я почти уверен в этом) - есть какие-нибудь подсказки?

1 Ответ

0 голосов
/ 29 января 2019

Вы можете создать один 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 возвращает только одну строку.

...