3

次のような関数があります。

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にクエリの結果を返すにはどうすればよいですか?

4

2 に答える 2

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$

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。1 つの関数からさまざまなデータ型を返すには、この妥協が必要です。すべてのデータ型は にキャストできるためtext、これは明らかな共通点です。

ARRAYところで、すべての単一の値のラッパーが何に適しているかを想像するのに苦労しています。私はあなたがそれを落とすことができると思います。

于 2013-05-21T18:40:55.317 に答える
3

PostgreSQL 関数は、実行前に結果の型を固定する必要があります。実行の後半でタイプを指定することはできません。一時テーブルを使用するか、カーソルを使用するという 2 つの回避策しかありません。

PLpgSQL 言語は、あまりにも一般的なルーチンには適していません。厳密でクリーンなビジネス ルールの実装には適しています。また、一般的なクロス集計計算、一般的な監査、または同様の一般的なタスクには適していません。動作しますが、コードは遅く、通常は保守性が高くありません。

ただし、クエリに返信する場合は、出力カーソルを使用できます

http://okbob.blogspot.cz/2008/08/using-cursors-for-generating-cross.html

于 2013-05-21T18:23:18.573 に答える