我有一个看起来像这样的函数:
CREATE OR REPLACE FUNCTION mffcu.test_ty_hey()
RETURNS setof record
LANGUAGE plpgsql
AS $function$
Declare
cname1 text;
sql2 text;
Begin
for cname1 in
select array_to_string(useme, ', ') from (
select array_agg(column_name) as useme
from(
select column_name::text
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'crosstab_183'
and ordinal_position != 1
) as fin
) as fine
loop
sql2 := 'select distinct array['|| cname1 ||'] from mffcu.crosstab_183';
execute sql2;
end loop;
END;
$function$
我用这个函数调用函数:
select mffcu.test_ty_hey()
如何在没有创建表/临时表的情况下返回sql2
查询的结果?
答案 0 :(得分:4)
虽然@Pavel是对的,当然,你的错综复杂的功能可能会被解开:
CREATE OR REPLACE FUNCTION mffcu.test_ty_hey()
RETURNS SETOF text[] LANGUAGE plpgsql
AS $func$
DECLARE
cname1 text;
BEGIN
FOR cname1 IN
SELECT column_name::text
FROM information_schema.columns
WHERE table_name = 'crosstab_183'
AND table_schema = 'mffcu'
AND ordinal_position <> 1
LOOP
RETURN QUERY
EXECUTE format('SELECT DISTINCT ARRAY[%I::text]
FROM mffcu.crosstab_183', cname1);
END LOOP;
END
$func$
format()
需要PostgreSQL 9.1或更高版本。在9.0中,您可以用以下代码替换:
EXECUTE 'SELECT DISTINCT ARRAY['|| quote_ident(cname1) ||'::text]
FROM mffcu.crosstab_183';
呼叫:
select * FROM mffcu.test_ty_hey();
通过将每列投射到text
,我们得出一致的数据类型,可用于声明RETURN
类型。必须做出这种妥协以从一个函数返回各种数据类型。每种数据类型都可以转换为text
,因此这是明显的共同点。
ARRAY
包装器应该有什么用处。我想你可以放弃它。
答案 1 :(得分:3)
PostgreSQL函数在执行之前应该具有固定的结果类型。您无法在执行后期指定类型。只有两种解决方法 - 使用临时表或使用游标。
PLpgSQL语言不适用于过于通用的例程 - 它有利于实现严格和干净的业务规则。而且通用交叉表计算或通用审计或类似的通用任务都很糟糕。它工作正常,但代码较慢,通常维护得不好。
但回复您的查询,您可以使用输出游标
示例http://okbob.blogspot.cz/2008/08/using-cursors-for-generating-cross.html