1

私はカスタムタイプを持っています:

create type some_type as (
    some_bool_param     boolean, 
    str                 varchar
);

このタイプのフィールドを含むテーブルを作成し、いくつかのデータを挿入します。

create table test_table (
    strs some_type
);

insert into test_table(strs) values
  ((false, 'First str'))
, ((false, 'Second str '))
, ((false, 'Third str'))
, ((false, 'Yet another str'));

そして今、私はデータのセットを返そうとしsome_typeます:

create or replace function get_str() returns setof some_type as
$$
declare
    r some_type;
begin
    for r in 
        select * from test_table loop
    return next r;
    end loop;
    return;
end;

私は電話しますget_str()

select * from get_str();

しかし、エラーが発生します:

ERROR:  error in boolean type value: "(f,"First str")"
CONTEXT:  PL/pgSQL function "get_str" line 4 at FOR by result of SELECT

どうすれば修正できますか?

4

3 に答える 3

5
create or replace function get_str() returns setof some_type as
$$
declare
    r some_type;
begin
    for r in 
        select strs from test_table loop
    return next r;
    end loop;
    return;
end;

念のため:テーブルを宣言するとその行タイプも宣言されるため、CREATE TYPEここで個別に指定する必要はありません。これも機能します:

create table test_table (
    some_bool_param     boolean, 
    str                 varchar
);

insert into test_table values (false, 'First str');
insert into test_table values (false, 'Second str ');
insert into test_table values (false, 'Third str');
insert into test_table values (false, 'Yet another str');

create or replace function get_str()
returns setof test_table as
$$
    SELECT  *
    FROM    test_table;
$$
LANGUAGE sql;
于 2012-06-04T08:13:45.780 に答える
4

この種の関数のために、現在のバージョンのPostgreSQLでループする必要はもうありません。RETURN QUERY代わりに使用してください:

CREATE OR REPLACE FUNCTION get_str()
  RETURNS SETOF test_table AS
$func$
BEGIN
   RETURN QUERY
   TABLE test_table;  -- shorthand for: SELECT * FROM test_table
END
$func$  LANGUAGE plpgsql;

または、@QuassnoiのようなSQL関数が提供されています。これにより、ネストされた複合型(SETOF test_table、ではなくSETOF some_type)が返されることに注意してください。

奇妙なことに、これも機能します。

CREATE OR REPLACE FUNCTION get_str5()
  RETURNS SETOF some_type AS
$func$
   TABLE test_table;
$func$ LANGUAGE sql;

外側の行のラッパーは静かに削除されます。これは控えめに言ってもPostgresのちょっと変わったものです。

エラーについて

関数は次のように機能します。

CREATE OR REPLACE FUNCTION get_str()
  RETURNS TABLE (strs some_type) AS
$func$
BEGIN
   FOR strs IN
       SELECT (t.strs).* FROM test_table t
   LOOP
      RETURN NEXT r;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

太字部分に注意してください。FORループ内の行またはレコードタイプへの割り当ては、サブフィールドごとに行われます。これは通常は便利ですが、ネストされた複合型を操作する場合は混乱します。

some_typeテーブル行()内にtest_table複合型( )があります-2つのレベルのネスト。それは通常、人が望むものではありませんが、それはあなたが私たちに提示したものです。

あなたは2回分解/アンラップする必要があります。

  • 元のコードは、外側の行ラッパーを。でのみ分解しselect * from test_tableます。

  • @Quassnoiが提案する修正select strs from test_tableも同じように失敗します。strsは直接参照によってテーブル行から分解されますが、strsそれでも割り当て前にそれ自体を分解する必要がある行タイプです。

于 2012-06-04T11:25:28.960 に答える
2

その宣言によれば、関数get_str()はsome_type、1つのブール値と1つのvarcharを持つ2つの列である構造を持つレコードのセットを返すことになっています。

関数は実際には、入力された1列のレコードのセットを返しますsome_type

に置き換えreturn next r;てみてくださいreturn next r.strs;

于 2012-06-04T08:03:46.533 に答える