PostgreSQL动态向前取计数值

PostgreSQL动态向前取计数值,sql,postgresql,cursor,plpgsql,postgresql-9.2,Sql,Postgresql,Cursor,Plpgsql,Postgresql 9.2,我使用以下函数从表中检索一批ID。此函数被用作OFFSET和LIMIT子句,似乎性能较差 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 B

我使用以下函数从表中检索一批ID。此函数被用作
OFFSET
LIMIT
子句,似乎性能较差

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;
我希望将
前取
计数
作为参数传入,但我找不到实现此目的的方法。引用$3不起作用,我还尝试了以下方法:

EXECUTE 'RETURN QUERY FETCH FORWARD ' || $3 || ' FROM c;';
如果有任何帮助,我们将不胜感激。

您会感到困惑,它们相似但不相同。特别是,在plpgsql中没有
前取
计数

direction子句可以是SQL
FETCH
命令中允许的任何变体,但可以获取多行的变体除外;即,它可以是
下一个
上一个
第一个
最后一个
绝对
计数,
相对
计数,
向前
,或
向后

在plgpsql中,一次只能获取一行并处理(或返回)它。 还有一个:

注意:此页面描述了在SQL命令级别使用游标。 如果您试图在PL/pgSQL函数中使用游标,则规则 它们是不同的

您可以在plpgsql中打开该游标,然后单击。但只有当您想从一个大游标中获取多个不同的片段以节省开销时,这才有意义。否则,一个普通的
FOR
循环(带自动光标)或一个简单的
选择
偏移
限制
肯定更快。游标主要用于返回给客户端并由客户端使用:

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;

我的回答回答了你的问题吗?嗨,欧文,谢谢你的回答。抱歉,我花了这么长时间才发表评论。要求改变了,这意味着这个问题变得毫无意义。我很感谢您提供的解决方案,但是
取前计数
确实有效,而
计数
值不能是动态的。因此,
fetchforward10
会很高兴地返回10个结果。