postgresql迭代n个记录
我有一个表student_list它只包含student_id一列和100行。 我需要同时获取10-10条记录,然后执行一些操作postgresql迭代n个记录,sql,postgresql,plpgsql,postgresql-9.4,postgresql-9.5,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 ne
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中的NEXT 5提取到myrow中您的代码不应该工作
FETCH NEXT 10
从游标中取出10行,但INTO
子句只取第一行,其他行丢失。MyRow是复合变量-它只能容纳一行
我有一个错误:
ERROR: FETCH statement cannot return multiple rows
LINE 6: fetch 10 from r into re;
^
这是正确的结果
简短且可能最正确的解决方案是在SELECT中使用FOR。该语句在内部使用游标,在第一次迭代中获取10行,在其他迭代中获取50行
因此:
你想做什么就做什么
若您想要显式地使用游标(并且确实想要在块中获取),那个么您需要使用更多的循环。下面的代码有点奇怪,我在这里写它只是为了教育——我不这么认为它对实际生活有任何好处
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;
$$;
内部对于IN-query
使用光标。所以FOR IN EXECUTE FETCH
是通过游标从另一个游标读取,这是一个性能上的废话,而且是一个非常难看的代码
重要事项-PostgreSQL没有表格变量-因此您无法为一个变量分配更多行,也无法从一个变量填充更多行
但是您的请求看起来像是过早的优化。最快和最有效的是命令:
INSERT INTO newtbl SELECT studentId FROM student_list
SQL可以很好地处理大规模操作。100万行算不了什么只有在您真正需要游标时才使用它我不明白,您有一个标量函数,所以我想您不想返回一组记录。然而,您选择了多达10条记录,并且可能想要获取更多。如何决定从哪个记录中提取返回值?我有100行。我需要处理1到10行,然后11到20,然后21到30到100。。。当我运行函数时,它只运行1到10。为什么Oracle PL/SQL被标记?您所做的就是将条目写入一个新表吗?或者是否涉及其他操作?是的,我也执行一些其他操作。我关心的是假设我在student_list表中有一百万条记录,这意味着游标将运行一百万次。。因此,我需要花费大量的时间来提高myrow在从cur1获取下一个10中的性能;--这很好,今天就学到了。SQL错误[42P11]:错误:无法以游标形式打开获取查询。@Charlie木匠 - 我忘记了,所以PLpgSQLFETCH
与SQLFETCH
语句不同。在这种情况下,必须使用动态SQL(要使用真正的SQLFETCH
语句),这是非常难看的。但我写了一个例子。@Charlie木匠 - 请参阅plpgsql源代码<“代码>对于在选择中”
在内部使用预取,并且每次都使用预取,这只是进程内调用。@Charlie木匠 - 对于唯一的SQL解决方案,您应该使用窗口函数和分组依据
。你可以试试我的扩展dbms\U sql。它支持此功能。
INSERT INTO newtbl SELECT studentId FROM student_list