我有一个返回游标的过程。
create or replace procedure pkg_test(cur out sys_refcursor) is
begin
insert into tb_test values(1);
insert into tb_test values(2);
insert into tb_test values(3);
open cur for
select * from tb_test;
delete from tb_test;
commit;
end pkg_test;
这很好。
现在我已经为某些性能问题创建了一个全局临时表,如下所示。
create global temporary table tb_test_GTT (deal_id int)
on commit delete rows;
create or replace procedure pkg_test(cur out sys_refcursor) is
begin
insert into tb_test_GTT values(1);
insert into tb_test_GTT values(2);
insert into tb_test_GTT values(3);
open cur for
select * from tb_test_GTT;
delete from tb_test_GTT;
commit;
end pkg_test;
现在,当我尝试从游标中获取数据时,出现以下错误:-
ORA-08103: object no longer exists.
我可以通过添加提交保留行来纠正此错误,但我想知道原因。
答案 0 :(得分:2)
提交后,您的数据不再存在。这就是临时表在Oracle中的工作方式。
游标基本上是对表的引用。您无法返回不存在的对象,因此会发生错误,因为引用的数据不再在那里。
由于这种方法将数据存储在内存中,因此您可以考虑返回Table Type对象。
Reference from the Official Documentation says:
REF CURSOR是PL / SQL数据类型,其值是数据库上查询工作区的内存地址。本质上,REF CURSOR是数据库上结果集的指针或句柄。 REF CURSOR具有以下特征:
REF CURSOR引用数据库上的内存地址。因此,客户端必须在REF CURSOR的生命周期内连接到数据库才能访问它。
REF CURSOR涉及额外的数据库往返。在将REF CURSOR返回给客户端时,直到客户端打开REF CURSOR并请求数据后,才返回实际数据。请注意,只有在用户尝试读取数据之后,才可以检索数据。