Podría funcionar así:
CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
RETURNS SETOF record AS
$func$
BEGIN
EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as
select *
from '
|| orig_name
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';
-- other work on view tmp
-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
-
Tenga en cuenta el uso del tipo de identificador de objeto
regclass
para evitar automáticamente la inyección de SQL. -
No use la sintaxis obsoleta
var ALIAS for $1
si no es necesario. Declare los nombres de los parámetros en su lugar. -
No usaría la palabra clave
temp
como identificador, incluso si eso está permitido. Usandotmp
en su lugar. -
Utilice
RETURN QUERY
para devolver un conjunto de registros. Incluso puede ser una llamada estática sinEXECUTE
. Sin embargo, está devolviendo registros anónimos y Postgres exige una lista de definición de columna con cada llamada:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Esto es bastante difícil de manejar.
Mejores soluciones
Si sabes el tipo de devolución (incluso si los nombres de las tablas están cambiando, la lista de columnas puede compartir los mismos tipos), declararlo en el momento de la creación. Considere esta pregunta relacionada:
PostgreSQL:ERROR:42601:se requiere una lista de definición de columna para las funciones que devuelven "registro"
Si el tipo de devolución varía con el nombre de la tabla proporcionado, todavía hay una solución mucho mejor. Dado que está creando una vista con SELECT * FROM tbl
, puede utilizar el tipo conocido de la tabla en sí como polimórfico
parámetro:
CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
RETURNS SETOF anyelement AS
$func$
BEGIN
EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
SELECT * FROM %s
WHERE trigger_changed > %L
ORDER BY trigger_changed DESC'
,pg_typeof(orig_name)
,data_tt);
-- other work on view tmp
-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
Llamada simplificada:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
También usando format()
para una concatenación de cadenas segura y sencilla.
Más detalles en esta respuesta relacionada:
Refactorizar una función PL/pgSQL para devolver el resultado de varias consultas SELECT