0

このリンクhttp://microjet.ath.cx/WebWiki/ResultPaginationWithPostgresql.htmlを読んだ後、ページネーションにカーソルを使用することにしました。しかし、plpgsqlで結果をフェッチする方法がわからないようです。

これが私の機能です

CREATE OR REPLACE FUNCTION get_pagination_custom_word_moderation(_moderation_id bigint, _is_black boolean, _index integer, _max_result integer)
    RETURNS TABLE(word_id bigint,
        word character varying,
        is_num_rlpcm boolean,
        is_word_bund boolean,
        note text,
        create_time timestamp without time zone,
        last_update timestamp without time zone) AS
$BODY$
DECLARE custom_word_moderation_cursor CURSOR FOR
    SELECT
        word_id,
        word,
        is_num_rlpcm,
        is_word_bund,
        note,
        create_time,
        last_update
    FROM
        custom_word_moderation
    WHERE
        moderation_id=_moderation_id
    AND is_black=_is_black;
BEGIN

MOVE ABSOLUTE _index FROM custom_word_moderation_cursor;
RETURN QUERY FETCH _max_result FROM custom_word_moderation_cursor;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

エラーは次のとおりです。

ERROR:  syntax error at or near "$1"
LINE 1:  FETCH  $1  FROM  $2 
                ^
QUERY:   FETCH  $1  FROM  $2 
CONTEXT:  SQL statement in PL/PgSQL function "get_pagination_custom_word_moderation" near line 18

********** Error **********

ERROR: syntax error at or near "$1"
SQL state: 42601
Context: SQL statement in PL/PgSQL function "get_pagination_custom_word_moderation" near line 18

問題は、カーソルからフェッチ結果を返す方法にあると思います。

4

1 に答える 1

1

あなたがやろうとしていることは実装されていません。クライアントが好きなように行をフェッチできるように、カーソルはそのように返されることを意図しています。特に大きな結果のために。そのために で関数を定義しますRETURNS refcursor

変数の明示的な割り当てを使用して機能させることはできますが、それを組み合わせるのは難しいです... plpgsql のコンテキストでは、カーソルのSQLと同じキーワードとは異なる意味を持つため、カーソルも必要になります。そして、あなたはしなければならないでしょうFOR LOOPOUTRETURNS TABLEOPENDECLAREDECLAREFETCH .. INTO ..

代わりに、カーソルを使用しない単純な同等のものを使用します。

CREATE OR REPLACE FUNCTION get_pagination_custom_word_moderation(
                         _moderation_id bigint, _is_black boolean
                       , _index integer, _max_result integer)
    RETURNS TABLE(word_id bigint,
        word varchar,
        is_num_rlpcm boolean,
        is_word_bund boolean,
        note text,
        create_time timestamp,
        last_update timestamp) AS
$func$
BEGIN
   RETURN QUERY
   SELECT word_id
         ,word
         ,is_num_rlpcm
         ,is_word_bund
         ,note
         ,create_time
         ,last_update
   FROM   custom_word_moderation
   WHERE  moderation_id = _moderation_id
   AND    is_black = _is_black
   OFFSET _index
   LIMIT  _max_result;
END
$func$ LANGUAGE plpgsql;

または、SQL 関数を使用するとさらに簡単になります。

CREATE OR REPLACE FUNCTION get_pagination_custom_word_moderation(
                         _moderation_id bigint, _is_black boolean
                       , _index integer, _max_result integer)
    RETURNS TABLE(word_id bigint,
        word varchar,
        is_num_rlpcm boolean,
        is_word_bund boolean,
        note text,
        create_time timestamp,
        last_update timestamp) AS
$func$
   SELECT word_id
         ,word
         ,is_num_rlpcm
         ,is_word_bund
         ,note
         ,create_time
         ,last_update
   FROM   custom_word_moderation
   WHERE  moderation_id = $1
   AND    is_black = $2
   OFFSET $3
   LIMIT  $4;
$func$ LANGUAGE sql;

$nバージョン 9.2 より前の SQL 関数ではパラメーターを名前で参照できないため、関数本体で表記法を使用しています。

実際にtable のすべての列を返したい場合は、さらに単純化できます。

CREATE OR REPLACE FUNCTION get_pagination_custom_word_moderation(
                         _moderation_id bigint, _is_black boolean
                       , _index integer, _max_result integer)
    RETURNS SETOF custom_word_moderation AS
$func$
   SELECT *
   FROM   custom_word_moderation
   WHERE  moderation_id = $1
   AND    is_black = $2
   OFFSET $3
   LIMIT  $4;
$func$ LANGUAGE sql;
于 2013-02-01T23:13:12.597 に答える