¿Puede la cláusula 'return' devolver columnas fuente que no están insertadas?


14

Aquí hay un ejemplo mínimo de mi problema del mundo real:

create table t(id serial primary key, rnd double precision);

por supuesto, puede devolver las columnas insertadas con una returningcláusula:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *;
/*
| ID |            RND |
|----|----------------|
|  9 | 0.203221440315 |
*/

También puede devolver un literal:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *, 1.0 dummy;
/*
| ID |            RND | DUMMY |
|----|----------------|-------|
| 11 | 0.594980469905 |     1 |
*/

pero no puede devolver las columnas de origen:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *, w.rnd;
/*
ERROR: missing FROM-clause entry for table "w": with w as (insert into t(rnd) values(random()) returning *) insert into t(rnd) select random() from w returning *, w.rnd
*/

¿Hay alguna forma de w.rndsalir de la returningcláusula final ?

db <> violín aquí


En MS SQL Server, solo la declaración MERGE permite que se devuelvan columnas adicionales. Quizás eso también funcione para postgres.
Sebastian Meine

Respuestas:


12

La documentación en la RETURNINGcláusula dice:

Una expresión para ser calculada y devuelta por el comando INSERT después de insertar cada fila. La expresión puede usar cualquier nombre de columna de la tabla nombrada por nombre_tabla. Escriba * para devolver todas las columnas de las filas insertadas.

Esto claramente no se aplica a las columnas de otra tabla.

Aunque realmente no entiendo el punto del problema (es decir, por qué haces esto, me imagino que es porque es una versión demasiado abstracta del original), una posible solución puede ser:

WITH w AS (INSERT INTO t(rnd) VALUES (random()) RETURNING *),
     x AS (INSERT INTO t(rnd) SELECT random() FROM w RETURNING *)
SELECT w.rnd, x.rnd
  FROM w, x;

Es decir, puede colocar más de un CTE grabable al comienzo de una consulta. Por favor, vea esto en acción en dbfiddle .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.