PostgreSQL迭代n条记录

时间:2018-07-24 11:36:28

标签: sql postgresql plpgsql postgresql-9.4 postgresql-9.5

我有一个表 student_list ,它只包含 student_id 一列和100行。 我需要同时获取10-10条记录,然后执行一些操作。

 CREATE OR REPLACE FUNCTION loop_fetch()
  RETURNS void AS
$BODY$
DECLARE
myrow student_list%rowtype;
cur1 CURSOR FOR SELECT * FROM student_list ;
BEGIN
 OPEN cur1;
    LOOP
    -- i need to fetch rows based on limit
    FETCH NEXT 10 FROM cur1 INTO myrow;
        exit when myrow  IS NULL;
        INSERT INTO new_tbl SELECT myrow.student_id ;
    END LOOP;
    CLOSE cur1;  
END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

任何实现此方法的建议-从cur1到myrow中获取下5个

1 个答案:

答案 0 :(得分:0)

您的代码不起作用。 FETCH NEXT 10从光标处获取10行,但是INTO子句仅占据第一行,其他丢失。 MyRow是复合变量-它只能容纳一行。

我遇到一个错误:

ERROR:  FETCH statement cannot return multiple rows
LINE 6:   fetch 10 from r into re;
          ^

这是正确的结果。

最简短且可能是最正确的解决方案是使用FOR IN SELECT。该语句在内部使用游标,在第一次迭代中获取10行,在其他迭代中获取50行。

所以:

DECLARE r record;
BEGIN
  FOR r IN SELECT * FROM student_list 
  LOOP
    INSERT INTO newtbl VALUES(r.*);
  END LOOP;
END;

几乎可以满足您的所有需求。

如果要显式使用游标(并且确实要在块中进行获取),则需要使用更多的循环。下面的代码有点奇怪,我在这里只是为了教育而写-不要认为它对实际生活有任何好处。

CREATE OR REPLACE FUNCTION loop_fetch()
RETURNS void AS
$BODY$
DECLARE
 myrow student_list%rowtype;
 cur1 CURSOR FOR SELECT * FROM student_list ;
BEGIN
  OPEN cur1;
  LOOP
    -- i need to fetch rows based on limit
    FOR myrow IN FETCH NEXT 10 FROM cur1
    LOOP
      INSERT INTO new_tbl SELECT myrow.student_id ;
    END LOOP;
    EXIT WHEN NOT FOUND;
  END LOOP;
  CLOSE cur1;  
END;
$BODY$
LANGUAGE plpgsql VOLATILE;

此代码应该可以工作,但是很疯狂。

重要的事情-PostgreSQL没有表格变量-因此您不能为一个变量分配更多的行,也不能从一个变量填充更多的行。

但是您的请求看起来像是过早的优化。最快,最有效的是命令:

INSERT INTO newtbl SELECT studentId FROM student_list

SQL可以很好地处理大量操作。 1M行什么都不是。 仅在确实需要时使用游标