To może działać tak:
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;
-
Zwróć uwagę na użycie typu identyfikatora obiektu
regclass
aby automatycznie uniknąć wstrzyknięcia SQL. -
Nie używaj przestarzałej składni
var ALIAS dla $1
jeśli nie musisz. Zamiast tego zadeklaruj nazwy parametrów. -
Nie użyłbym słowa kluczowego
temp
jako identyfikator, nawet jeśli jest to dozwolone. Korzystanie ztmp
zamiast tego. -
Użyj
POWRÓT ZAPYTANIA
zwrócić zestaw rekordów. Może to być nawet wywołanie statyczne bezEXECUTE
. Jednak zwracasz anonimowe rekordy a Postgres żąda listy definicji kolumn przy każdym połączeniu:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Jest to raczej nieporęczne.
Lepsze rozwiązania
Jeśli wiesz zwracany typ (nawet jeśli nazwy tabel się zmieniają, lista kolumn może mieć te same typy), zadeklaruj go w czasie tworzenia. Rozważ to powiązane pytanie:
PostgreSQL:BŁĄD:42601:lista definicji kolumn jest wymagana dla funkcji zwracających "rekord"
Jeśli typ zwrotu jest różny z podaną nazwą tabeli nadal istnieje znacznie lepsze rozwiązanie. Ponieważ tworzysz widok za pomocą SELECT * FROM tbl
, możesz wykorzystać dobrze znany typ samej tabeli jako polimorficzne
parametr:
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;
Uproszczone połączenie:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Również przy użyciu format()
do bezpiecznego i prostego łączenia ciągów.
Więcej szczegółów w tej powiązanej odpowiedzi:
Refaktoryzuj funkcję PL/pgSQL, aby zwrócić dane wyjściowe różnych zapytań SELECT