Declare cur_1 Sys_Refcursor; cur_2 Sys_Refcursor; v_1 VARCHAR2(30); v_2 VARCHAR2(30); v_3 VARCHAR2(30); v_4 VARCHAR2(30); Begin OPEN cur_1 for Select * from tab1@dblink1; Loop Fetch cur_1 into v_1,v_2; EXIT WHEN cur_1%NOTFOUND; OPEN cur_2 for Select * from tab2@dblink1 where col1 = v_1 and col2 = v2; Loop Fetch cur2 into v_3,v_4; Exit when cur_2%notfound; INSERT INTO local.tab3 values (v_1,v_2,v_3,v_4); END Loop; close cur_2; End Loop; close cur_1; END;
abobe程序编译,但是当我运行它时,我得到以下错误:
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
…(Few more ‘No more data to read from socket’)IO Error: Connection reset by peer: socket write error
Process exited.
有趣的是,当我注释掉整个内循环时,程序运行没有错误.所以我知道内部循环有问题(我尝试只在内部循环中注释insert语句并得到相同的错误).
我的localdb和dblink1数据库都有相同的版本:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 – 64bit Production
PL/sql Release 11.2.0.1.0 – Production
CORE 11.2.0.1.0 Production
TNS for 64-bit Windows: Version 11.2.0.1.0 – Production
NLSRTL Version 11.2.0.1.0 – Production
这些错误通常是由另一个严重错误引起的,例如ORA-600错误.一个严重的问题,服务器进程崩溃,甚至无法向客户端发送正确的错误消息. (这些错误的另一个常见原因是sqlNET.EXPIRE_TIME或其他一些杀死旧会话的进程导致的网络断开.)
查看警报日志以查找原始错误消息.
在此目录中查找文件alert_ [name] .log:从v $parameter中选择值,其中name =’background_dump_dest’;
找到特定的错误消息和详细信息后,请转至support.oracle.com.使用“ora-600工具”,然后在ORA-600消息后查找第一个数字.
对于该特定类型的ORA-600错误,通常会有一篇或多篇文章.使用确切的版本和平台来缩小可能的错误列表. (但如果文章中的“受影响的版本”是错误的,请不要感到惊讶.甲骨文声称“修复版x.y”并非总是如此.)
这些文章通常会更详细地解释问题是如何发生的,可能的解决方法以及通常涉及补丁或升级的解决方案.
在实践中,你很少想解决这些问题. “典型”建议是联系Oracle支持部门以验证您是否确实遇到了同样的问题,获得了修补程序,获得了许可并关闭了环境,然后应用了修补程序.然后可能意识到补丁不起作用.恭喜你,你浪费了很多时间.
相反,您通常可以通过对查询或过程进行细微更改来避免此问题. Oracle中有很多功能,几乎总有另一种方法可以做到这一点.如果代码看起来有点奇怪,添加注释以警告未来的程序员:“这段代码看起来很奇怪,以避免错误X,应该在版本Y中修复.”
对此代码的具体建议
如果这真的是你的整个过程,你应该用这样的东西替换它:
insert into local.tab3(col1,col2,col3,col4) select tab1.col1,tab1.col2,tab2.col1,tab2.col2 from tab1@dblink1 tab1 join tab2@dblink1 tab2 on tab1.col1 = tab2.col1 and tab1.col2 = tab2.col2;
通常,如果可能,您应该始终在sql中执行操作.特别是如果你可以避免打开许多游标.特别是如果您可以避免将多个游标打开到远程数据库.