Объединение операторов INSERT в CTE, изменяющем данные, с выражением CASE
Мой вопрос является своего рода дополнением к прекрасному ответу Эрвина Брандштеттера вэта тема на правильное использованиеWITH
.
Мой старый запрос выглядит так:
WITH x AS (
INSERT INTO d (dm_id)
SELECT dm_id
FROM dm, import i
WHERE dm.dm_name = i.dm_name
RETURNING d_id
), y AS (
INSERT INTO z (d_id)
SELECT d_id
FROM x
RETURNING z_id
)
INSERT INTO port (z_id)
SELECT z_id
FROM y;
Это работает как шарм. Но теперь другая таблица (r
) был добавлен (такая же структура, как таблица)d
) и с этим возможность, что либоd_id
или жеr_id
должен быть добавлен в таблицуz
, Это в зависимости от тогоdm_name
или жеrm_name
пуст в таблицеimport
, Так что мой теоретический подход был бы примерно таким:
SELECT dm_name, rm_name
,CASE WHEN dm_name != '' THEN
WITH x AS (
INSERT INTO d (dm_id)
SELECT dm_id
FROM dm, import i
WHERE dm.dm_name = i.dm_name
RETURNING d_id
), y AS (
INSERT INTO z (d_id)
SELECT d_id
FROM x
RETURNING z_id
)
INSERT INTO port (z_id)
SELECT z_id
FROM y
END
,CASE WHEN rm_name != '' THEN
WITH x AS (
INSERT INTO r (rm_id)
SELECT rm_id
FROM rm, import i
WHERE rm.rm_name = i.rm_name
RETURNING r_id
), y AS (
INSERT INTO z (r_id)
SELECT r_id
FROM x
RETURNING z_id
)
INSERT INTO port (z_id)
SELECT z_id
FROM y
END
FROM import;
Но PostgreSQL говорит мне:
синтаксическая ошибка в или около "INSERT INTO port (z_id)"
хотя эта часть запроса должна быть правильной, поскольку она уже работает.
Я надеюсь, что вы можете помочь мне решить это. :)
Для лучшего понимания - вот структура таблицы:
CREATE TABLE import (
dm_name character varying,
rm_name character varying
-- many other columns which are not relevant
);
CREATE TABLE dm (
dm_id integer NOT NULL, -- serial
dm_name character varying
-- plus more columns
);
CREATE TABLE d (
d_id integer NOT NULL, -- serial
dm_id integer -- references dm.dm_id
-- plus more columns
);
CREATE TABLE rm (
rm_id integer NOT NULL, -- serial
rm_name character varying
-- plus more columns
);
CREATE TABLE r (
r_id integer NOT NULL, -- serial
rm_id integer -- references rm.rm_id
-- plus more columns
);
CREATE TABLE z (
z_id integer NOT NULL, -- serial
r_id integer, -- references r.r_id
d_id integer -- references d.d_id
-- plus more columns
);
CREATE TABLE port (
p_id integer NOT NULL, -- serial
z_id integer, -- references z.z_id
-- plus more columns
);
Таблица импорта не знает идентификаторы, так как они генерируются в процессе распыления. Таблицы dm и rm предназначены для моделей устройств, которые уже были извлечены из таблицы импорта. Таблицы d и r предназначены для реальных устройств. Поскольку только порт может иметь только r-устройство или d-устройство или ни одного, z-таблица была представлена, чтобы иметь только одно поле в таблице портов, представляющее все возможности. Таблицы d / r и dm / rm нельзя комбинировать, так как они имеют разные специальные столбцы в зависимости от типов устройств.