如何在PL/SQL中释放游标?

4

我会在SQL Server和Oracle上编码。
当我在SQL Server上编码时,我使用这个:

OPEN curUSERS;
CLOSE curUSERS;
DEALLOCATE curUSERS;

现在,在我编写Oracle代码时,我使用以下内容:
OPEN curUSERS;
CLOSE curUSERS;

我在PL / SQL中看到了DEALLOCATE关键字,但当我使用该语句时,出现了错误。
DEALLOCATE(curUSERS);

它报错了。在PL/SQL中我该如何做同样的事情(解除分配)?


1
如果这是一个关键字,我期望调用方式类似于OPEN和CLOSE,例如DEALLOCATE curUSERS,不需要括号。但我从未见过或使用过这个。你能否编辑问题并提供Oracle文档的链接?谢谢。 - Bob Jarvis - Слава Україні
你有幻觉!Oracle PL/SQL 没有 deallocate 关键字:Oracle 11.2 PL/SQL 保留字和关键字。我不了解 SQL Server,但在 Oracle 中关闭/释放/清理游标是一个步骤操作:close - user272735
2个回答

10

Oracle 不需要显式地释放游标的内存。只需使用 CLOSE(cursor)


这有点误导人。显式打开的游标使用的内存直到游标被显式清理(或会话关闭)才会释放。在Oracle术语中,清理阶段是“关闭”。 - user272735
1
这个回答是正确的。小细节(参见文档)。您可以调用close来显式地关闭游标并释放其资源。如果您没有显式调用close,则游标将在声明它的块的结尾关闭(对于在程序块/方法中声明的游标),或者在会话结束时关闭(对于在包级别声明的游标)。 - GolezTrol

0

尽可能避免使用显式游标。显式游标需要更多的代码,并且速度较慢,因为它们不会自动进行批量收集。游标FOR循环简单快捷。

示例模式

drop table table1;
create table table1 as select 1 a from dual;

显式游标 - 更多的代码,更差的性能

declare
    v_a number;
    cursor table1_cursor is select a from table1;
begin
    open table1_cursor;
    loop
        fetch table1_cursor into v_a;
        exit when table1_cursor%notfound;
        dbms_output.put_line(v_a);
    end loop;
    close table1_cursor;
end;
/

游标循环 - 更少的代码,更好的性能

begin
    for table1_rows in (select a from table1)
    loop
        dbms_output.put_line(table1_rows.a);    
    end loop;
end;
/

for循环仍然不如使用bulk collect的forall语句高效。如果性能是最终目标,那么首先摆脱循环。 - Lalit Kumar B
1
@LalitKumarB 是的,如果可能的话,最好不要使用循环。问题只是直接涉及到读取数据,其中for循环与任何显式批量收集一样有效。读和写通常是相互关联的,但根据我的经验,通常读取比写入要多得多,并且在读取时获得自动批量收集已经足够好了。 - Jon Heller
1
我们需要编写显式游标,即使使用了bulk collect;以使用limit子句。 - Ram Dwivedi
@RamDwivedi 光标for循环也会为您处理这个问题。它们自动使用100的限制。 - Jon Heller
1
@RamDwivedi 理论上和实践中,100对于任何大小都是可以的。通过批量收集,可以节省处理时间,消除SQL和PL/SQL之间的切换。2的限制减少了50%的开销,3减少了66%等等。当限制到达100时,剩余的开销不到1%。即使对于大型数据集,从100到100,000,000移动几乎没有优势。 - Jon Heller
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接