Може да работи така:
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;
-
Обърнете внимание на използването на тип идентификатор на обект
regclass
за автоматично избягване на SQL инжектиране. -
Не използвайте остарелия синтаксис
var ALIAS за $1
ако не ти се налага. Вместо това декларирайте имена на параметри. -
Не бих използвал ключовата дума
temp
като идентификатор, дори ако това е разрешено. Използване наtmp
вместо това. -
Използвайте
ВРЪЩАНЕ НА ЗАЯВКА
за връщане на набор от записи. Това дори може да бъде статично повикване безEXECUTE
. Вие обаче връщате анонимни записи и Postgres изисква списък с дефиниции на колони с всяко обаждане:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Това е доста тромаво.
По-добри решения
Ако знаете връщания тип (дори ако имената на таблиците се променят, списъкът с колони може да споделя едни и същи типове), декларирайте го по време на създаване. Обмислете този свързан въпрос:
PostgreSQL:ГРЕШКА:42601:изисква се списък с дефиниции на колони за функции, връщащи "запис"
Ако типът на връщане варира с предоставеното име на таблица все още има много по-добро решение. Тъй като създавате изглед с SELECT * FROM tbl
, можете да използвате добре познатия тип на самата таблица като polymorphic
параметър:
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;
Опростено повикване:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Също така се използва format()код>
за безопасно и просто конкатениране на низове.
Повече подробности в този свързан отговор:
Рефакторинг на PL/pgSQL функция, за да върне изхода на различни SELECT заявки