4

テーブルから Id のバッチを取得するために使用される次の関数があります。この関数は、OFFSETandLIMIT句のパフォーマンスが低いように見えるため、使用されています。

CREATE OR REPLACE FUNCTION getBatch(_workloadId VARCHAR, _offSet INT, _limit INT)
  RETURNS SETOF NUMERIC AS $$
DECLARE 
    c SCROLL CURSOR FOR
      SELECT id FROM workload WHERE workload_id = $1 ORDER BY id ASC; 
BEGIN

OPEN c;
MOVE FORWARD $2 IN c; 
RETURN QUERY FETCH FORWARD 10 FROM c;

END;
$$ LANGUAGE plpgsql;

をパラメーターとして渡したいのですFETCH FORWARDcountが、これを行う方法が見つかりません。$3 の参照は機能しません。次のことも試しました。

EXECUTE 'RETURN QUERY FETCH FORWARD ' || $3 || ' FROM c;';

どんな助けでも大歓迎です。

4

1 に答える 1

3

SQL カーソルを、似ているが同じではないPL/pgSQL カーソルと混同しています。特に、FETCH FORWARDcountplpgsql にはありません:

FETCH方向句は、複数の行をフェッチできるものを除いて、SQL コマンドで許可されているバリアントのいずれかにすることができます。つまり、、、、、カウント、カウント、、NEXTまたはのいずれかです。PRIORFIRSTLASTABSOLUTERELATIVEFORWARDBACKWARD

plgpsql では、一度に1 つの行のみをフェッチして処理 (または返す) できます。マニュアルには免責事項もあります。

: このページでは、SQL コマンド レベルでのカーソルの使用法について説明します。PL/pgSQL 関数内でカーソルを使用しようとしている場合、ルールは異なります。

そのカーソルを plpgsql で開き、ループして行を返すことができます。ただし、これは、オーバーヘッドを節約するために大きなカーソルから複数の個別のピースをフェッチする場合にのみ関係します。それ以外の場合は、単純なFORループ (自動カーソルを使用) または単純なSELECTwith OFFSETandのLIMIT方が確実に高速です。カーソルは主に、クライアントに返されて使用されることを意図しています。

CREATE OR REPLACE FUNCTION getbatch_ref(_cursor refcursor, _workload_id text)
  RETURNS refcursor AS
$func$
BEGIN
OPEN $1 SCROLL FOR
   SELECT id
   FROM   workload
   WHERE  workload_id = $2
   ORDER  BY id; 

   RETURN $1;
END
$func$ LANGUAGE plpgsql;

この関数は SQL で使用できます。

BEGIN;
SELECT getbatch_ref('c', 'foo');
MOVE  FORWARD 10 IN c; 
FETCH FORWARD 10 FROM c;

ROLLBACK; -- or COMMIT;

プレーン SQL を使用することもできます。

BEGIN;
DECLARE c SCROLL CURSOR FOR
   SELECT id
   FROM   workload
   WHERE  workload_id = 'foo'
   ORDER  BY id; 

-- OPEN c; -- only relevant in plpgsql
-- The PostgreSQL server does not implement an OPEN statement for cursors;
-- a cursor is considered to be open when it is declared. 
MOVE  FORWARD 10 IN c; 
FETCH FORWARD 10 FROM c;

ROLLBACK; -- or COMMIT;
于 2013-03-15T01:28:18.973 に答える