以“选择语句”格式从函数返回结果

pre*_*ose 3 sql postgresql function plpgsql

我有一个看起来像这样的函数:

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$
Run Code Online (Sandbox Code Playgroud)

我用这个调用函数:

select mffcu.test_ty_hey()
Run Code Online (Sandbox Code Playgroud)

如何在创建表/临时表的情况下返回sql2查询结果?

Erw*_*ter 5

虽然@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$
Run Code Online (Sandbox Code Playgroud)

format()需要 PostgreSQL 9.1 或更高版本。在 9.0 中,您可以替换为:

EXECUTE 'SELECT DISTINCT ARRAY['|| quote_ident(cname1) ||'::text]
         FROM   mffcu.crosstab_183';
Run Code Online (Sandbox Code Playgroud)

称呼:

select * FROM mffcu.test_ty_hey();
Run Code Online (Sandbox Code Playgroud)

通过将每一列强制转换为text可用于声明RETURN类型的一致数据类型。为了从一个函数返回各种数据类型,必须做出这种妥协。每种数据类型都可以转换为text,因此这是明显的共同点。

顺便说一句,我很难想象ARRAY每个值周围的包装器应该有什么用处。我想你可以放弃它。

  • @precose:它现在应该可以工作了,我修复了两个疏忽并进行了测试。 (2认同)