【问题标题】:PostgreSQL dynamic fetch foward count valuePostgreSQL 动态获取转发计数值
【发布时间】:2013-03-14 19:11:55
【问题描述】:

我有以下函数用于从表中检索一批 Id。这个函数被用作OFFSETLIMIT 子句似乎提供了很差的性能。

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;';

任何帮助将不胜感激。

【问题讨论】:

  • 我的回答是否回答了你的问题?
  • 您好欧文,感谢您的回复。对不起,我花了这么长时间才发表评论。需求改变意味着问题变得没有实际意义。我很欣赏您提供的解决方案,但是 FETCH FORWARD count 确实有效,除了 count 值不能是动态的。所以FETCH FORWARD 10 很乐意返回 10 个结果。

标签: sql postgresql cursor plpgsql postgresql-9.2


【解决方案1】:

您将SQL cursorsPL/pgSQL cursors 混淆了,它们相似但不相同。特别是plpgsql中没有FETCH FORWARDcount

direction 子句可以是 SQL FETCH 命令中允许的任何变体,除了那些可以获取多行的变体;即可以是NEXTPRIORFIRSTLASTABSOLUTEcount、RELATIVEcount、FORWARDBACKWARD

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

注意:本页描述了 SQL 命令级别的游标用法。 如果您尝试在 PL/pgSQL 函数中使用游标,则规则 不一样。

您可以在 plpgsql 和 loop to return rows 中打开该游标。但这仅在您想从大光标中获取多个不同的部分以节省开销时才有意义。否则一个简单的FOR 循环(带有自动光标)或一个简单的SELECTOFFSETLIMIT 肯定更快。游标主要用于返回给客户端并由客户端使用:

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;

【讨论】:

    猜你喜欢
    • 2021-04-11
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多