sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Una forma fácil de hacer que el tipo de devolución sea la tabla SETOF más campos adicionales?

podrías devuelve una fila completa como tipo compuesto y agrega algunas más:

CREATE OR REPLACE FUNCTION f_rowplus()
  RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$  LANGUAGE sql;

Pero luego, cuando usas la llamada simple:

SELECT * FROM f_rowplus();

Obtienes la fila de la tabla demo como tipo compuesto separado. Tendrías que llamar:

SELECT (rec).*,  add_int, add_txt FROM f_rowplus();

para obtener todo individual columnas Se requieren paréntesis.

Postgres es un poco inconsistente aquí. Si crea una función con:

CREATE OR REPLACE FUNCTION f_row2()
  RETURNS TABLE (rec demo) AS
...

luego el tipo compuesto demo se convierte silenciosamente en columnas individuales (descompuestas). No queda ningún vínculo con el tipo compuesto original. No puede hacer referencia a la columna de salida declarada rec en absoluto, ya que ha sido sustituida por las columnas del tipo descompuesto. Esta llamada daría como resultado un mensaje de error:

SELECT rec FROM f_row2();

Lo mismo aquí:

CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
  RETURNS SETOF demo AS
...

Sin embargo , tan pronto como agregue cualquiera más OUT columnas, el tipo compuesto se conserva como se declara (no se descompone) y puede:

SELECT rec FROM f_rowplus();

con la primera función.

Creé un SQL Fiddle demostrando las variantes.

Aparte
Cuando se utiliza una función que devuelve varias columnas en FROM list (como función de tabla) y descomponiendo en el SELECT lista como esta:

SELECT (rec).* FROM f_rowplus();

... la función todavía se evalúa una vez solamente - mientras llama y descomponiendo en el SELECT lista directamente así:

SELECT (f_rowplus()).*;  -- also: different result

... evaluaría una vez por cada columna en el tipo de retorno. Detalles: