我想创建一个函数,该函数返回从未知表创建的视图中的行:
CREATE OR REPLACE FUNCTION tt_query(text, timestamp without time zone)
RETURNS SETOF record AS
$$
DECLARE
orig_name ALIAS FOR $1;
data_tt ALIAS FOR $2;
BEGIN
[...]
EXECUTE 'create OR REPLACE TEMP view temp as
select *
from '
||orig_name
||' where trigger_changed >'
||quote_literal(data_tt)
||' ORDER BY trigger_changed DESC';
[...]--other work on view temp
--NOW I WANT RETURN THE ROW OF view temp
END;
$$
LANGUAGE plpgsql VOLATILE
好的我想(有你的帮助)这个:
表:
create table t(a integer, b text);
功能:
CREATE OR REPLACE FUNCTION f()
RETURNS SETOF record AS
$$
BEGIN
RETURN QUERY EXECUTE 'SELECT * FROM t';
END;
$$
LANGUAGE plpgsql VOLATILE
型:
CREATE TYPE y AS (
a int,
b text
);
现在可以吗?:
select * from f() as y;
在我的案例中,是一个变量,我在另一个函数中创建它
答案 0 :(得分:3)
它可以像这样工作:
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;
请注意使用object identifier type regclass
自动避免SQL注入。
如果您不需要,请不要使用过时的语法var ALIAS for $1
。改为声明参数名称。
我不会使用关键字temp
作为标识符,即使这是允许的。改为使用tmp
。
使用RETURN QUERY
返回一组记录。这甚至可以是没有EXECUTE
的静态呼叫。但是,每次通话都会返回匿名记录,Postgres要求列定义列表:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
这是相当笨拙的。
如果您知道返回类型(即使表名称正在更改,列列表可能共享相同的类型),请在创建时声明它。考虑这个相关的问题:
PostgreSQL: ERROR: 42601: a column definition list is required for functions returning "record"
如果返回类型与所提供的表名称不同,则仍有更好的解决方案。由于您使用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()
安全&简单的字符串连接。
此相关答案的更多细节:
Refactor a PL/pgSQL function to return the output of various SELECT queries