我有表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;
实现此方法的任何建议 - FETCH NEXT 5 FROM cur1 INTO myrow
最佳答案
你的代码不应该工作。 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;
几乎可以完成您想要的所有操作。
如果你想显式地使用游标(并且确实想以 block 的方式获取),则需要使用更多的周期。下面的代码有点奇怪,我在这里写它只是为了教育 - 不要认为它对实际生活有任何好处。
CREATE OR REPLACE FUNCTION loop_fetch()
RETURNS void AS
$BODY$
DECLARE
myrow student_list%rowtype;
cur1 CURSOR FOR SELECT * FROM student_list ;
rows int DEFAULT 0;
BEGIN
LOOP
-- i need to fetch rows based on limit
FOR myrow IN cur1
LOOP
INSERT INTO new_tbl SELECT myrow.student_id ;
END LOOP;
EXIT WHEN NOT FOUND;
rows := rows + 1;
EXIT WHEN rows = 10;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
这段代码应该可以工作,但它很疯狂。
或者您可以使用FOR IN EXECUTE
do $$
declare
c cursor for select * from generate_series(1,100);
r record;
begin
-- *** UGLY CODE, DON'T DO IT!!! ***
open c;
-- iteration over FETCH is possible only via
-- dynamic SQL. FOR statement uses FETCH internally
-- by default, and is nonsense use FETCH 2x
for r in execute 'fetch 10 from c'
loop
raise notice '%', r;
end loop;
close c;
-- *** UGLY CODE, DON'T DO IT!!! ***
end;
$$;
内部FOR IN 查询
使用游标。所以 FOR IN EXECUTE FETCH
是通过游标从另一个游标读取,这是性能废话,而且代码非常丑陋。
重要的事情 - PostgreSQL 没有表格变量 - 因此您不能为一个变量分配更多行,也不能从一个变量填充更多行。
但是您的请求看起来像是过早的优化。最快速、最有效的是命令:
INSERT INTO newtbl SELECT studentId FROM student_list
SQL可以很好地处理大量操作。 1M 行不算什么。 仅在确实需要时才使用光标。
关于sql - postgresql 迭代n条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51497593/