Det kan fungera så här:
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;
-
Observera användningen av objektidentifieringstypen
regclass
för att automatiskt undvika SQL-injektion. -
Använd inte den föråldrade syntaxen
var ALIAS för $1
om du inte måste. Deklarera parameternamn istället. -
Jag skulle inte använda nyckelordet
temp
som identifierare, även om det är tillåtet. Användertmp
istället. -
Använd
RETURN QUERY
för att returnera en uppsättning poster. Detta kan till och med vara ett statiskt samtal utanEXECUTE
. Du returnerar dock anonyma poster och Postgres kräver en kolumndefinitionslista med varje samtal:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Det här är ganska otympligt.
Bättre lösningar
Om du vet returtypen (även om tabellnamnen ändras, kan listan med kolumner dela samma typer), deklarera den vid skapandet. Tänk på den här relaterade frågan:
PostgreSQL:FEL:42601:en kolumndefinitionslista krävs för funktioner som returnerar "record"
Om returtypen varierar med det angivna tabellnamnet finns det fortfarande en mycket bättre lösning. Eftersom du skapar en vy med SELECT * FROM tbl
, kan du använda den välkända typen av själva tabellen som 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;
Förenklat samtal:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Använder även format()
för säker och enkel strängsammansättning.
Mer information i detta relaterade svar:
Refaktorera en PL/pgSQL-funktion för att returnera utdata från olika SELECT-frågor