A veces es útil obtener datos de las filas modificadas mientras se
manipulan. Los comandos INSERT, UPDATE,
DELETE y MERGE tienen una
cláusula opcional RETURNING que admite esto. El uso
de RETURNING evita realizar una consulta adicional a la
base de datos para recopilar los datos, y es especialmente valioso cuando de
otro modo sería difícil identificar las filas modificadas de manera confiable.
Los contenidos permitidos de una cláusula RETURNING son los mismos
que los de la lista de salida de un comando SELECT
(ver la Section 7.3). Puede contener nombres de columnas
de la tabla de destino del comando, o expresiones de valores utilizando esas
columnas. Una abreviatura común es RETURNING *, que selecciona
todas las columnas de la tabla de destino en orden.
En un INSERT, los datos predeterminados disponibles para
RETURNING son la fila tal como fue insertada. Esto no es tan
útil en inserciones triviales, ya que solo repetiría los datos proporcionados
por el cliente. Pero puede ser muy práctico cuando se confía en valores
predeterminados calculados. Por ejemplo, al usar una columna
serial para proporcionar
identificadores únicos, RETURNING puede devolver el ID asignado
a una nueva fila:
CREATE TABLE users (firstname text, lastname text, id serial primary key);
INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
La cláusula RETURNING también es muy útil
con INSERT ... SELECT.
En un UPDATE, los datos predeterminados disponibles para
RETURNING es el nuevo contenido de la fila modificada.
Por ejemplo:
UPDATE products SET price = price * 1.10 WHERE price <= 99.99 RETURNING name, price AS new_price;
En un DELETE, los datos predeterminados disponibles para
RETURNING es el contenido de la fila eliminada.
Por ejemplo:
DELETE FROM products WHERE obsoletion_date = 'today' RETURNING *;
En un MERGE, los datos predeterminados disponibles para
RETURNING es el contenido de la fila de origen más el contenido
de la fila de destino insertada, actualizada o eliminada. Dado que es bastante
común que el origen y el destino tengan muchas de las mismas columnas, especificar
RETURNING * puede provocar muchas columnas duplicadas, por lo
que a menudo es más útil calificarlo para devolver solo la fila de origen o la de
destino. Por ejemplo:
MERGE INTO products p USING new_products n ON p.product_no = n.product_no WHEN NOT MATCHED THEN INSERT VALUES (n.product_no, n.name, n.price) WHEN MATCHED THEN UPDATE SET name = n.name, price = n.price RETURNING p.*;
En cada uno de estos comandos, también es posible devolver explícitamente el contenido antiguo y nuevo de la fila modificada. Por ejemplo:
UPDATE products SET price = price * 1.10
WHERE price <= 99.99
RETURNING name, old.price AS old_price, new.price AS new_price,
new.price - old.price AS price_change;
En este ejemplo, escribir new.price es lo mismo que escribir
simplemente price, pero hace que el significado sea más claro.
Esta sintaxis para devolver valores antiguos y nuevos está disponible en los
comandos INSERT, UPDATE,
DELETE y MERGE, pero normalmente los valores
antiguos serán NULL para un INSERT, y los
nuevos valores serán NULL para un DELETE.
Sin embargo, existen situaciones en las que todavía puede ser útil para esos comandos.
Por ejemplo, en un INSERT con una cláusula
ON CONFLICT DO UPDATE,
los valores antiguos no serán NULL para las filas en conflicto.
Del mismo modo, si un DELETE se convierte en un UPDATE
mediante una regla de reescritura, los nuevos
valores pueden ser no NULL.
Si hay disparadores o triggers (Chapter 37) en la tabla de destino,
los datos disponibles para RETURNING son la fila modificada por
los disparadores. Por lo tanto, inspeccionar las columnas calculadas por los disparadores
es otro caso de uso común para RETURNING.