4

PL/pgSQL 関数を作成しようとしていますが、これは一時テーブルにデータを入力し、そこからすべての行を返す必要があります (後で結合されます) が、指定する戻り値の型がわかりません:

create or replace function pref_daily_misere() returns void as $BODY$
        begin

        create temporary table temp_best (id varchar not null) on commit drop;
        insert into temp_best (id) select id from pref_money where
            yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW')
            order by money desc limit 10;
        select id from temp_best;
        end;
$BODY$ language plpgsql;

上記のステートメントは単独で機能しますが、エラーが発生します

# select pref_daily_misere();
ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function "pref_daily_misere" line 7 at SQL statement

私のPostgreSQL 8.4.11データベースでそれを呼び出そうとしたとき。

これはおそらく、上記の戻り値 voidの指定が間違っているためですが、代わりに使用する戻り値の型がわかりません。戻り値の型を省略するとコンパイル エラーになります。

4

1 に答える 1

5

setof varchar戻り値の型を使用してからreturn query ...、関数内で使用したい。細かいマニュアルから:

39.6.1.2. RETURN NEXT と RETURN QUERY

RETURN NEXT expression;
RETURN QUERY query;
RETURN QUERY EXECUTE command-string [ USING expression [, ... ] ];

PL/pgSQL 関数がSETOF sometypeを返すように宣言されている場合、従うべき手順は少し異なります。その場合、返される個々のアイテムは一連のコマンドRETURN NEXTまたはRETURN QUERYコマンドによって指定され、引数のない最後のRETURNコマンドを使用して、関数の実行が終了したことを示します。

私はあなたがこのようなものがもっと欲しいと思います:

create or replace function pref_daily_misere() returns setof varchar as $BODY$
begin
    create temporary table temp_best (id varchar not null) on commit drop;
    insert into temp_best (id)
    select id
    from pref_money
    where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW')
    order by money
    desc limit 10;
    return query select id from temp_best;
    return;
end;
$BODY$ language plpgsql;

ただし、ここでは一時テーブルは無意味です。

注:の現在の実装では、上記で説明したように、関数から戻る前に結果セット全体RETURN NEXTを保存します。RETURN QUERY

そのため、PostgreSQL は結果セット全体を計算し、それ自体をキャッシュしています。あなたはこれを行うことができます:

create or replace function pref_daily_misere() returns setof varchar as $BODY$
begin
    return query
        select id
        from pref_money
        where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW')
        order by money
        desc limit 10;
    return;
end;
$BODY$ language plpgsql;

とにかく関数の最後に一時テーブルが削除されると確信しているので、削除する必要があります。

于 2012-06-10T22:29:22.697 に答える