3

列の動的セットを返す単純な関数が必要です。SOでいくつかの例を見つけましたが、最終的には次のようになります。

CREATE or replace FUNCTION getColumn(_column1 text, _column2 text, _column3 text, _table text)
  RETURNS TABLE(cmf1 text, cmf2 text, cmf3 text) AS $$
BEGIN
    RETURN QUERY EXECUTE 
        'SELECT ' 
            || quote_ident(_column1)::text || ' as cmf1,'
            || quote_ident(_column2)::text || ' as cmf2,'
            || quote_ident(_column3)::text || ' as cmf3'
        ' FROM '
            || quote_ident(_table); 
END;
 $$ LANGUAGE plpgsql;

この関数は varchar/text 列でのみ機能する必要があるため、次のテスト テーブルを作成しました。

create table test20130205 (
    a text,
    b text,
    c varchar,
    d text)
;

最後に、いくつかのテストを実行できます。

select * from getColumn('a','b','d','test20130205');
-- ok
select * from getColumn('a','b','c','test20130205');
-- error
ERROR:  structure of query does not match function result type
DETAIL:  Returned type character varying does not match expected type text in column 3.
CONTEXT:  PL/pgSQL function getcolumn(text,text,text,text) line 3 at RETURN QUERY

列 c (varchar) の型がキャスト前にチェックされているようです。これは奇妙に思えますが、何かを見逃していると思います。

機能を修正するにはどうすればよいですか?

(PostgreSQL 9.1)

4

1 に答える 1

6

現在の関数では、テキストへのキャストは出力列の値には適用されず、名前(の結果quote_ident)に適用されます。

キャストはクエリ自体の内部に移動する必要があります。

CREATE or replace FUNCTION getColumn(_column1 text, _column2 text, _column3 text, _table text)
  RETURNS TABLE(cmf1 text, cmf2 text, cmf3 text) AS $$
BEGIN
    RETURN QUERY EXECUTE 
        'SELECT ' 
            || quote_ident(_column1) || '::text as cmf1,'
            || quote_ident(_column2) || '::text as cmf2,'
            || quote_ident(_column3) || '::text as cmf3'
        ' FROM '
            || quote_ident(_table); 
END;
 $$ LANGUAGE plpgsql;
于 2013-02-04T12:30:53.233 に答える