Combinando instrucciones INSERT en un CTE modificador de datos con una expresión CASE
Mi pregunta es algún tipo de extensión a la excelente respuesta de Erwin Brandstetter eneste hilo sobre el uso correcto deWITH
.
Mi consulta anterior se ve así:
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;
Esto funciona como un encanto. Pero ahora, otra mesa (r
) se ha agregado (la misma estructura que la tablad
) y con ello la posibilidad de qued_id
or_id
tiene que ser agregado a la mesaz
. Esto, dependiendo de sidm_name
orm_name
está vacío en la mesaimport
. Entonces mi enfoque teórico sería algo como esto:
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;
Pero PostgreSQL me dice:
error de sintaxis en o cerca de "INSERT INTO port (z_id)"
aunque esa parte de la consulta debería ser correcta, ya que funciona.
Espero que me puedan ayudar a resolver esto. :)
Para una mejor comprensión, aquí está la estructura de la tabla:
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
);
La tabla de importación no conoce los identificadores, ya que se generan durante el proceso de atomización. Las tablas dm y rm son para modelos de dispositivos que ya se extrajeron de la tabla de importación. Las tablas d y r son para los dispositivos reales. Como un puerto solo puede tener un dispositivo r o un dispositivo d o ninguno, la tabla z se introdujo para tener solo un campo en la tabla de puertos que representa todas las posibilidades. Las tablas d / r y dm / rm no se pueden combinar ya que tienen columnas especiales diferentes según los tipos de dispositivo.