ORA-01002 使用临时表和 .Net 乱序获取
我在 Oracle 中有一个存储过程,我试图从 .Net Core 应用程序调用它。
该过程循环游标以填充全局临时表,并尝试将结果作为引用游标发送回。
Type ssp_rec_refcur Is Ref Cursor; -- Return ssp_rec;
Procedure temp_table_sel(p_ssp_rec_refcur Out ssp_rec_refcur) Is
Cursor cur_main Is
Select item1
,item2 etc..
From regular_table;
Begin
For c_rec In cur_main Loop
-execute some functions to get supplemtary data based on cursor row
--store values in temp table for ref cursor
Insert Into global_temp_table
Values
(c_rec.item1, c_rec.item2, c_rec.item3 etc...);
End If;
End If;
End Loop;
Open p_ssp_rec_refcur For
Select * From global_temp_table;
Exception
When Others Then
log_error($$plsql_Unit, 'temp_table_sel');
End temp_table_sel;
在数据库本身上进行测试时,这工作得很好,但是当我尝试从 .Net 执行它时,我收到错误:ora-01002 fetch out of order。
如果我提交一个 Commit;命令就在 select 语句之前,它消除了错误,但表随后为空,因为它在提交时删除了行;
如果我在 Select 语句之后放置 Commit,它会返回错误。
如何将临时表行读入引用游标而不触发“获取失序”错误?
I have a stored proc in Oracle that I am trying to call from a .Net Core app.
The proc loops through a cursor to populate a Global Temporary table, and attempts to send the result back as a ref cursor.
Type ssp_rec_refcur Is Ref Cursor; -- Return ssp_rec;
Procedure temp_table_sel(p_ssp_rec_refcur Out ssp_rec_refcur) Is
Cursor cur_main Is
Select item1
,item2 etc..
From regular_table;
Begin
For c_rec In cur_main Loop
-execute some functions to get supplemtary data based on cursor row
--store values in temp table for ref cursor
Insert Into global_temp_table
Values
(c_rec.item1, c_rec.item2, c_rec.item3 etc...);
End If;
End If;
End Loop;
Open p_ssp_rec_refcur For
Select * From global_temp_table;
Exception
When Others Then
log_error($plsql_Unit, 'temp_table_sel');
End temp_table_sel;
This works fine when testing on the DB itself, but when I try to execute it from .Net, I am getting the error: ora-01002 fetch out of sequence.
If I put a Commit; command right before the select statement it gets rid of the error, but the table is then empty as it deletes rows on commit;
If I put a Commit after the Select statement, it goes back the error.
How can I read the temporary table rows into a ref cursor without triggering a Fetch Out of Sequence error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这就是我认为正在发生的事情。
问题在于临时表是使用属性“ON COMMIT DELETE ROWS;”定义的,因此当它在数据库端运行时,它没有问题,因为没有提交。
但是,当从 .Net 调用它时,Oracle.ManagedDataAccess.dll 在每个事务结束时都会执行自动提交,这会导致临时表删除其行,从而在我读取游标之前使游标无效。
我的解决方法是将临时表设置为“ON COMMIT PRESERVE ROWS;”这样自动提交就不会删除它们,并且现在会按预期读取游标。
我在过程中进行了更改以获取用户的会话 ID 并将其存储在临时表中,然后如果用户在同一会话中再次查询,则按会话 ID 从表中删除以避免任何重复数据,因为它不会删除交易后自动。
So here's what I think was happening.
The problem is that the temp table was defined with the attribute "ON COMMIT DELETE ROWS;", so when it ran on the DB side it was fine because there is no commit.
However when calling it from .Net, Oracle.ManagedDataAccess.dll does an autocommit at the end of every transaction, which caused the temp table to delete it's rows, thus invalidating the cursor before I could read it.
My work around was set the temp table to "ON COMMIT PRESERVE ROWS;" so that the autocommit didn't delete them and it now reads the cursor as exptected.
I put a change in the proc to get the user's session ID and store that in the temp table as well, then delete from the table by session ID if the user queries again in the same session to avoid any duplicate data since it will not delte automatically after the transaction.