ORACLE异常——ORA-01000: maximum open cursors exceeded

Exception : java.sql.SQLException: ORA-01000: maximum open cursors exceeded

游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字。用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。

Oracle 使用 init.ora 中的初始化参数 OPEN_CURSORS 指定一个会话一次最多可以拥有的游标数。缺省值为 50。要获得数据库中 OPEN_CURSORS 参数的值,可以使用以下查询:
SQL> show parameter open_cursors;
NAME                                 TYPE        VALUE
———————————— ———– —————
open_cursors                         integer     300

重要的是将 OPEN_CURSORS 的值设置得足够大,以避免应用程序用尽所有打开的游标。应用程序不同,该值也不同。即便会话打开的游标数未达 OPEN_CURSORS 指定的数量(即设置的值高于实际需要的值), 也不会增加系统开销。

第一种情况:未释放游标造成。

很多朋友在Java开发中,使用Oracle数据库的时候,经常会碰到有ORA-01000: maximum open cursors exceeded.的错误。 
实际上,这个错误的原因,主要还是代码问题引起的。 
ora-01000: maximum open cursors exceeded. 
表示已经达到一个进程打开的最大游标数。 
这样的错误很容易出现在Java代码中的主要原因是:Java代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。 
一般来说,我们在写Java代码的时候,createStatement和prepareStatement都应该要放在循环外面,而且使用了这些Statment后,及时关闭。最好是在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭。 
对于出现ORA-01000错误这种情况,单纯的加大open_cursors并不是好办法,那只是治标不治本。实际上,代码中的隐患并没有解除。 
而且,绝大部分情况下,open_cursors只需要设置一个比较小的值,就足够使用了,除非有非常特别的要求。

第二种情况:建表时STORAGE参数设置太小。

昨天说的有些错误,应该是physical_attributes_clause语句。
我们系统的数据量比较大,近200张表,有些表一天要插入1000000条左右的数据。
表是使用ER/STDIO设计的,然后直接生成建表的脚本,由于没有设置physical_attributes_clause语
句中的建表参数,因此使用了默认的参数。好像是INITIAL 10K NEXT 10K PCTFREE 20 PCTUSED 50
由于表的存储空间太小,在很短的时间内就会装满,因此ORACLE就需要不停为30多张表(数据量较大的)申请空间。于是在程序运行了一段时间后,开始出现ORA-01000: maximum open cursors exceeded的错误。我将游标大小改到了300,还是出现错误,改到1000以后开始出现了ORA-01001:invalid cursors。再怎么加大open_cursors的数量都无济于事。
使用select * from v$open_cursor查询,发现有几百条的INSERT语句游标没有释放。
开始怀疑是程序调用的问题,仔细检查程序没有发现问题。但是发现对某张表进行TRUNCATE操作后,对此表进行插入的游标全部释放,于是开始怀疑是表结构本身的问题。
重新设置了建表参数,将数据量最大的表的INITIAL和NEXT均设置为50M。
ALTER TABLE tablename STORAGE( INITIAL N NEXT N);
至今未再出现同样的错误。


注:蓝色字体出自以下网络资源。

http://www.itpub.net/thread-25663-1-1.html

http://wenku.baidu.com/view/3bbb55160b4e767f5acfcef2.html

阅读更多

ORA-01000: maximum open cursors exceeded 错误,急!!!!

10-31

我用OleDb INSERT ORACLE数据库的一个表的数据,但会出来这个如下的错误:rnrn“/QAR”应用程序中的服务器错误。rn--------------------------------------------------------------------------------rnrnORA-01000: maximum open cursors exceeded rn说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 rnrn异常详细信息: System.Data.OleDb.OleDbException: ORA-01000: maximum open cursors exceededrnrn源错误: rnrnrn行 75: rn行 76: MyCommand = New OleDbCommand(mysql, MyConnection)rn行 77: MyCommand.executenonquery()rn行 78: rn行 79: rn rnrn源文件: d:\inetpub\wwwroot\QAR\WebForm1.aspx 行: 77 rnrn堆栈跟踪: rnrnrn[OleDbException (0x80040e14): ORA-01000: maximum open cursors exceeded]rn System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(Int32 hr) +41rn System.Data.OleDb.OleDbCommand.ExecuteCommandTextForMultpleResults(tagDBPARAMS dbParams, Object& executeResult) +89rn System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult) +62rn System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult) +65rn System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method) +112rn System.Data.OleDb.OleDbCommand.ExecuteNonQuery() +54rn ASP.WebForm1_aspx.Page_Load(Object sender, EventArgs e) in d:\inetpub\wwwroot\QAR\WebForm1.aspx:77rn System.Web.UI.Control.OnLoad(EventArgs e) +67rn System.Web.UI.Control.LoadRecursive() +29rn System.Web.UI.Page.ProcessRequestMain() +724rnrn但我并未用到游标啊,而且不是每次都出现这错误,有时执行是正确的。rn疑惑。。。。时好时坏,不知哪里出了问题rn望大家解惑,急,谢谢!!!!!rn(只能修改INIT。ORA的游标的设置吗?网上查到的英文文档好象是这意思,但我一般是不能这样做的,而且我也觉得与这没什么关系。有其他解决方法吗?谢谢!) rn

求助:java.sql.SQLException: ORA-01000 ====ORA-01000: maximum open cursors exceeded

07-06

rnrn 最经在河南XX电信项目中出现ORA-01000: maximum open cursors exceeded.的错误,已经苦恼我很长时间。 rn 现象:过一段时间就会提示ORA-01000: maximum open cursors exceeded错误,系统就不能用。需要重启才能解决。这个故障提示明显的是游标超出数量。曾DBA将游标的数量增加到1000.可是还是出现这个问题。 rn 在网上找一堆资料: rn”表示已经达到一个进程打开的最大游标数。这样的错误很容易出现在Java代码中的主要原因是:Java代码在执行conn.createStatement()和 conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。 rn 一般来说,我们在写Java代码的时候,createStatement和prepareStatement都应该要放在循环外面,而且使用了这些Statment后,及时关闭。最好是在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭。 rn 对于出现ORA-01000错误这种情况,单纯的加大open_cursors并不是好办法,那只是治标不治本。实际上,代码中的隐患并没有解除。 rn 而且,绝大部分情况下,open_cursors只需要设置一个比较小的值,就足够使用了,除非有非常特别的要求。 “ rn 根据网上资料查询用到的游标: rnselect sid,count(sid)cc rnfrom v$open_cursor where user_name = 'SZNEWS' group by sid order by cc desc rn找出了占用最大的632个游标的session id, rnselect * from v$open_cursor where user_name = 'SZNEWS' and sid=62 rn确认了是我的程序的sql。 rn从plsqldev 界面直接杀掉同sid的session,session是INACTIVE状态; rn再一查632个cursor,已经没有了。 rn但是服务不行啦,只能重启服务器。 rn对632个cursor发现锁中占用最多的游标的SQL语句由下面的代码产生的: rn (代码框架用”Hibernate+spring) rn HibernateTemplate ht = getHibernateTemplate(); rn AddSheetInfo addSheetInfo = (AddSheetInfo) logObject; rn ht.save(addSheetInfo); rn return addSheetInfo; rn 1:不知道自己的解决问题方法是否正确; rn 2:不知道怎么会有使游标不释放的原因是什么。 rnrn 郁闷中.................... rn

【求助】maximum open cursors exceeded

04-05

只要执行查询就会出现ORA-01000: maximum open cursors exceeded 。是因为我在循环中没有关闭什么吗???怎么才能在一次循环后关闭打开的游标呢??? rn谢谢指点!!! (不好意思,复制过来格式变乱了)rn rn rn说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 rn rn异常详细信息: System.Data.OracleClient.OracleException: ORA-01000: maximum open cursors exceeded rn rn源错误: rn rn rn行 230: rn行 231: cmd.CommandText = "select sum(reqcount) from ussdstate"+tabname.ToString()+" where (startby=0)"; rn行 232: odr = cmd.ExecuteReader(); rn行 233: if(odr.HasRows==true) rn行 234: rnrnrn rnstring strussdstateconnection="Data Source=RADIAN;user=ussd;password=radian"; rnconn = new OracleConnection(strussdstateconnection); rnconn.Open(); rn rnfor(int m=0;m<=intDays3;m++) rn rnOracleCommand cmd = conn.CreateCommand(); rn cmd.CommandText = "select count(*) from ussdstate"+tabname.ToString(); rn OracleDataReader odr; rnodr = cmd.ExecuteReader(); rn rn if(odr.HasRows==true) rn rn odr.Read(); rn try rn rn tem1 = Convert.ToInt32(odr[0].ToString()); rn rn catch(FormatException FE) rn rn tem1 = 0; rn rn rn rn else rn rn tem1=0; rn rn rn cmd.CommandText = "select count(*) from ussdstate"+tabname.ToString()+" where ((causevalue=0) or (causevalue=34) or (causevalue between 73 and 144) or (causevalue>149))"; rn rn odr = cmd.ExecuteReader(); rn if(odr.HasRows==true) rn rn odr.Read(); rn try rn rn tem2 = Convert.ToInt32(odr[0].ToString()); rn rn catch(FormatException FE) rn rn tem2 = 0; rn rn rn rn else rn rn tem2=0; rn rn rncmd.CommandText = "select sum(reqcount) from ussdstate"+tabname.ToString(); rnodr = cmd.ExecuteReader(); rnif(odr.HasRows==true) rn rn odr.Read(); rn try rn rn tem3 = Convert.ToInt32(odr[0].ToString()); rn rn catch(FormatException FE) rn rn tem3 = 0; rn rn rn else rn rn tem3=0; rn rn rn cmd.CommandText = "select count(*) from ussdstate"+tabname.ToString()+" where (startby=0)"; rnodr = cmd.ExecuteReader(); rnif(odr.HasRows==true) rn rn odr.Read(); rn try rn rn tem4 = Convert.ToInt32(odr[0].ToString()); rn rn catch(FormatException FE) rn rn tem4 = 0; rn rn rn rn else rn rn tem4=0; rn rn rn cmd.CommandText = "select count(*) from ussdstate"+tabname.ToString()+" where ((startby=0) and ((causevalue=0) or (causevalue=34) or (causevalue between 73 and 144) or (causevalue>149)))"; rn odr = cmd.ExecuteReader(); rn if(odr.HasRows==true) rn rn odr.Read(); rn try rn rn tem5 = Convert.ToInt32(odr[0].ToString()); rn rn catch(FormatException FE) rn rn tem5 = 0; rn rn rn rn else rn rn tem5=0; rn rn rn cmd.CommandText = "select sum(reqcount) from ussdstate"+tabname.ToString()+" where (startby=0)"; rnodr = cmd.ExecuteReader(); rnif(odr.HasRows==true) rn rn odr.Read(); rn try rn rn tem6 = Convert.ToInt32(odr[0].ToString()); rn rn catch(FormatException FE) rn rn tem6 = 0; rn rn rn rn else rn rn tem6=0; rn rn rn total += tem1; rn success += tem2; rn reqcount += tem3; rn ms_total += tem4; rn ms_success += tem5; rn ms_reqcount += tem6; rn rn rn odr.Close(); rn rn System.DateTime tempdate = startDateTime.AddDays(m+1); rn string strtempdate = tempdate.ToString("u"); rnstrtempdate = strtempdate.Substring(0,10); rntabname = checkdaytime(strtempdate); rn

没有更多推荐了,返回首页