Het zou als volgt kunnen werken:
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;
-
Let op het gebruik van de object-identificatietype
regclass
om automatisch SQL-injectie te voorkomen. -
Gebruik niet de verouderde syntaxis
var ALIAS for $1
als het niet hoeft. Declareer in plaats daarvan parameternamen. -
Ik zou het trefwoord
temp
niet gebruiken als identifier, zelfs als dat is toegestaan.tmp
gebruiken in plaats daarvan. -
Gebruik
RETURN QUERY
om een reeks records te retourneren. Dit kan zelfs een statische oproep zijn zonderEXECUTE
. U retourneert echter anonieme records en Postgres eist een kolomdefinitielijst bij elke oproep:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Dit is nogal onpraktisch.
Betere oplossingen
Als je weet het retourtype (zelfs als tabelnamen veranderen, kan de lijst met kolommen dezelfde typen delen), declareer het bij het maken. Overweeg deze gerelateerde vraag:
PostgreSQL:FOUT:42601:een kolomdefinitielijst is vereist voor functies die "record" retourneren
Als het retourtype varieert met de opgegeven tabelnaam is er nog steeds een veel betere oplossing. Aangezien u een weergave maakt met SELECT * FROM tbl
, kunt u het bekende type tabel zelf gebruiken als polymorf
parameter:
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;
Vereenvoudigde oproep:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Gebruikt ook format()
voor veilige en eenvoudige aaneenschakeling van strings.
Meer details in dit gerelateerde antwoord:
Refactor een PL/pgSQL-functie om de uitvoer van verschillende SELECT-query's te retourneren