@ ver1PORT_">

[20181220]ORA-1000 "maximum open cursors exceeded".txt

来源:这里教程网 时间:2026-03-03 12:46:55 作者:

[20181220]ORA-1000 "maximum open cursors exceeded".txt --//链接提到http://www.itpub.net/thread-2107244-1-1.html的ora-1000错误.我自己以前也遇到一例,实际上现在开发也没有解决. --//实在不想再提交改正报告. --//当时没有记录,现在重新记录看看. 1.环境: XXXX> @ ver1 PORT_STRING         VERSION        BANNER ------------------- -------------- ---------------------------------------------------------------------------- x86_64/Linux 2.4.xx 11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production XXXX> show parameter open_cursors NAME         TYPE    VALUE ------------ ------- ------ open_cursors integer 8000 --//哈哈,没有办法为了规避这个错误,只能设置很大的值.我清楚的记得出现问题时我设置1000(可以动态设置,退出就生效). --//依旧还是出现问题,只不过次数大大减少,查询dba_outstanding_alerts有时也有警告. --//注意这个参数表示的是max # cursors per session,而不是整个数据库打开cursors的总数.(我以前在这里理解错误!!) --//设置很大并不会导致共享内存之类的消耗. --//在我的测试环境执行: SYS@book> @ hide  open_cursors NAME                       DESCRIPTION                                   DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE -------------------------- --------------------------------------------- ------------- ------------- ------------ _close_cached_open_cursors close cursors cached by PL/SQL at each commit TRUE          FALSE         FALSE open_cursors               max # cursors per session                     FALSE         300           300 XXXX> select * from (select sid,count(*) from V$OPEN_CURSOR group by sid order by 2 desc) where rownum<=5;        SID   COUNT(*) ---------- ----------       1357        154       6019        153       2018        152       2019        152        713        152 --//现在是上午,一般到下午就会很多(如果不退出应用程序的话). --//出现这个问题,只要使用者退出再进入就ok了. 2.分析: --//随便看一个sid=713. --//我当时查询select * from V$OPEN_CURSOR where sid=713;发现里面有一些sql语句非常相似. XXXX> select * from (select sql_text,count(*) from V$OPEN_CURSOR where sid=713 group by sql_text order by 2 desc) where rownum<=2; SQL_TEXT                                                       COUNT(*) ------------------------------------------------------------ ----------   SELECT lis_requisition_info.requisition_state,                     66   SELECT lis_requisition_info.requisition_state,                     63 --//有两种风格的写法,查询看看这些相似语句是什么?   SELECT A.FORCE_MATCHING_SIGNATURE, COUNT (*)     FROM v$sqlarea a    WHERE sql_text LIKE '  SELECT lis_requisition_info.requisition_state%' GROUP BY A.FORCE_MATCHING_SIGNATURE; FORCE_MATCHING_SIGNATURE   COUNT(*) ------------------------ ----------     10585972023561820239        464      5952195431604116876       3390     10068562918106072429       1075      3489546227993117356       1261 --//相似的执行语句很多,我已经设置cursor_sharing=force,也就是不应该存在没有使用绑定变量的情况. --//执行如下: select SQL_FULLTEXT from v$sqlarea where FORCE_MATCHING_SIGNATURE=3489546227993117356; --//注我曾经在toad看这些语句感觉都是一样的,toad界面写这些语句已经格式化了. XXXX> select len  from (select sql_fulltext,dbms_lob.getlength(SQL_FULLTEXT) len from  v$sqlarea where FORCE_MATCHING_SIGNATURE=3489546227993117356 order by 2) where rownum<=10;  LEN ---- 2379 2379 2380 2380 2381 2381 2382 2382 2383 2383 10 rows selected. --//我不显示sql_fulltext字段太长,仅仅显示语句的长度,你可以发现长度逐步增加. 3.单独取出语句保存为文件比较看看. R:\>diff -Nur a1.txt a2.txt --- a1.txt      Thu Dec 20 10:30:59 2018 +++ a2.txt      Thu Dec 20 10:31:22 2018 @@ -44,4 +44,4 @@           lis_requisition_info.return_method,           lis_requisition_info.return_accept_remark      FROM lis_requisition_info -    WHERE (receive_time BETWEEN to_date(:"SYS_B_0",:"SYS_B_1") AND to_date(:"SYS_B_2",:"SYS_B_3")) AND (position2 = :"SYS_B_4") AND (receive_dept = :"SYS_B_5") +     WHERE (receive_time BETWEEN to_date(:"SYS_B_0",:"SYS_B_1") AND to_date(:"SYS_B_2",:"SYS_B_3")) AND (position2 = :"SYS_B_4") AND (receive_dept = :"SYS_B_5") --//可以看出差别,在WHERE语句前有空格,可以猜测语句在代码中没有关闭光标,并且每次使用拼接sql语句.在where前面都加一个空格. --//还可以猜测程序代码是相互借鉴的,错误也是一样的类似,查看FORCE_MATCHING_SIGNATURE=5952195431604116876,后面的条件如下: WHERE (send_time BETWEEN to_date(:"SYS_B_0",:"SYS_B_1") AND to_date(:"SYS_B_2",:"SYS_B_3")) AND (send_person = :"SYS_B_4") --//实际上这个错误很容易修正,我提交了错误,可惜到现在都没有修正,二期项目是时我再次提交修正报表,还是依旧. --//我真心不知道开发怎么想的,我曾经跟一些同行有过类似的交流,我感觉开发的惰性在作怪,在他们看来,只要程序代码 --//没有错,就不需要改动. --//我曾经想过,删除open_cursors的设置,使用缺省值(缺省值=50),这样开发是否会改代码...^_^. --//我还依稀记得出现错误时,没有任何人检查问题出在哪里,对于使用者也习惯了,程序时不时报出错误是正常的,退出继续使用就ok了. --//那里知道这样丧失了学习提高的机会,不积跬步何以至千里,不积小胜何以来大胜.

相关推荐