使用oracle PLSQL Bulk COLLET with limit子句将整个数据放入集合
我有一个名为EMP的表,有140000行,我需要将整个数据保存到集合中。如何使用“BULK COLLECT..LIMIT”子句功能扩展集合并将整个数据加载到集合中 以下逻辑未提供所需结果,因为数据已被新记录覆盖。请向我建议逻辑使用oracle PLSQL Bulk COLLET with limit子句将整个数据放入集合,oracle,plsql,bulk-operations,Oracle,Plsql,Bulk Operations,我有一个名为EMP的表,有140000行,我需要将整个数据保存到集合中。如何使用“BULK COLLECT..LIMIT”子句功能扩展集合并将整个数据加载到集合中 以下逻辑未提供所需结果,因为数据已被新记录覆盖。请向我建议逻辑 DECLARE CURSOR c_get_employee IS SELECT empno, ename, deptno, sal FROM em
DECLARE
CURSOR c_get_employee IS
SELECT empno,
ename,
deptno,
sal
FROM emp;
TYPE t_employee
IS TABLE OF c_get_employee%ROWTYPE INDEX BY inary_integer;
l_employee T_EMPLOYEE;
BEGIN
OPEN c_get_employee;
LOOP
FETCH c_get_employee bulk collect INTO l_employee limit 300;
EXIT WHEN l_employee.count = 0;
END LOOP;
CLOSE c_get_employee;
FOR i IN 1..l_employee.count LOOP
dbms_output.Put_line (L_employee(i).ename
||'<-->'
||L_employee(i).sal);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.Put_line ('Unexpected error :- '
|| SQLERRM);
END;
声明
光标c_get_employee为
选择empno,
艾娜,
德普诺,
萨尔
来自emp;
类型t_雇员
是c_get_employee%行类型索引的表,由一个二元整数表示;
l_员工T_员工;
开始
打开c_get_employee;
环
取c_get_employee bulk collect至l_employee limit 300;
l_employee.count=0时退出;
端环;
关闭c_get_员工;
对于1..l_employee.count循环中的i
dbms_output.Put_line(L_employee(i).ename
||''
||L_员工(i.sal);
端环;
例外情况
当其他人
dbms_output.Put_行('意外错误:-'
||SQLERRM);
结束;
您过早退出循环。您需要在for循环之后停止fetch循环,然后关闭游标
另外,正如@APC指出的,退出条件应该使用获取结果的计数,而不是游标上的NOTFOUND
。否则,如果最后一次提取的记录少于提取大小,则NOTFOUND
将为true,循环将错误终止
试试这个:
DECLARE
CURSOR c_get_employee IS
SELECT empno,
ename,
deptno,
sal
FROM emp;
TYPE t_employee
IS TABLE OF c_get_employee%ROWTYPE INDEX BY binary_integer;
l_employee T_EMPLOYEE;
BEGIN
OPEN c_get_employee;
LOOP
FETCH c_get_employee bulk collect INTO l_employee limit 3;
EXIT WHEN l_employee.count = 0;
FOR i IN 1..l_employee.count LOOP
dbms_output.Put_line (L_employee(i).ename
||'<-->'
||L_employee(i).sal);
END LOOP;
END LOOP;
CLOSE c_get_employee;
EXCEPTION
WHEN OTHERS THEN
dbms_output.Put_line ('Unexpected error :- '
|| SQLERRM);
END;
声明
光标c_get_employee为
选择empno,
艾娜,
德普诺,
萨尔
来自emp;
类型t_雇员
是c_get_employee%行类型索引的表,由二进制_整数表示;
l_员工T_员工;
开始
打开c_get_employee;
环
取c_get_employee bulk collect到l_employee limit 3中;
l_employee.count=0时退出;
对于1..l_employee.count循环中的i
dbms_output.Put_line(L_employee(i).ename
||''
||L_员工(i.sal);
端环;
端环;
关闭c_get_员工;
例外情况
当其他人
dbms_output.Put_行('意外错误:-'
||SQLERRM);
结束;
以下逻辑未给出所需结果
胡猜:你只得到12排。这是一个熟悉的限制条款。这条线就是问题所在:
EXIT WHEN c_get_employee%NOTFOUND;
您在EMP中有14条记录:限制为3意味着您收集了四组记录。最后一次获取仅收集2条记录。PL/SQL将其解释为NOTFOUND
。解决方案是检查集合的大小:
EXIT WHEN l_employee.count() = 0;
我希望将整个数据加载到集合中并关闭光标,然后打开集合并将数据用于业务逻辑 这不是批量收集的方式。。。限制工作。LIMIT子句的目的是,呃,限制一次获取的记录数量。当查询的数据太大而无法在一次获取中处理时,我们需要这样做。PL/SQL集合是会话内存分配中保存的内存结构:如果它们太大,将破坏PGA。(定义“太大”将取决于DBA如何配置PGA。)
因此,如果您有一个小的结果集,请放弃LIMIT子句,在一次获取中填充集合。但是,如果您有足够的数据需要LIMIT子句,则需要在fetch循环中包含业务逻辑循环。嗨,Gurvinder Singh,我的要求是,首先,我希望将游标中的整个数据保存到集合中。然后,我希望关闭游标并打开集合,并希望使用集合中的此数据创建业务逻辑。大容量集合将在下一次获取中替换变量中的数据。除此之外,你不应该阅读集合中的整张表格。如果记录的数量很小,可能会增加获取大小以匹配记录的数量。我同意您的观点(大容量收集将在下一次获取中替换变量中的数据),但我希望使用“大容量收集…限制”从游标加载整个数据“将功能加载到集合中。@MastanSky,那么您想加载所有行,但也要限制它们吗?”?不清楚当您不想限制任何内容时,为什么会有
limit
子句。“下面的逻辑没有给出所需的结果”。如果您定义预期输出并解释实际输出的差异,而不是让我们猜测问题所在,那么每个人的生活通常都会更轻松。亲爱的团队,我想将整个数据加载到集合中并关闭光标。然后,我想打开集合并将数据用于业务逻辑。