如何获得ORACLE数据库游标的最大数(100分)

  • 主题发起人 主题发起人 jetcoyuan
  • 开始时间 开始时间
J

jetcoyuan

Unregistered / Unconfirmed
GUEST, unregistred user!
用JSP/SERVLET开发应用网站时,当执行SQL语句时,
提示:
出现错误 ORA-01000: 超出打开游标的最大数
后台数据库是中文ORACLE8.17,数据库连接用JAVABEAN实现,并在Finally里
statement=null;
rs.close;
rs=null;
db.disconnect;
数据库CURSOR已经增大至300,已经更新了classes12.zip,仍不行
请问:如何解决以上问题?如何在JSP程序中得到数据库目前已经使用的游标数
 
检查你的存储过程或者触发器,
这可能不是你的sql造成的,也许其他的某个查询或者操作
打开了太多的游标而没有关闭。
 
没有用到存储过程或者触发器,开发环境为WIN2000 SERVER,WAS3.5,VAJ3.5
 
请看源代码:
类com.wf.db.cMdbResult
{
public com.ibm.db.SelectResult rs=null;
}
public boolean close() {
rs.close();
rs=null;
}

类com.wf.db.conpool
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import com.ibm.db.*;
import java.sql.*;
import javax.sql.*;
import com.ibm.ejs.dbm.jdbcext.*;
import javax.naming.*;

public class conpool{
private Connection conn=null;

public static DataSource ds = null;
private DatabaseConnection connBean=null;
private int MaxRowCount=0;
}
public void disconnect()
{
if (conn != null)
conn.close();
}
public boolean GetDBConnection(DataSource ds,String user,String password ) {
conn = ds.getConnection(user, password);

connBean = new DatabaseConnection(conn);
}
public boolean GetDBConnection(Connection conn1 ) {
conn=conn1;
connBean = new DatabaseConnection(conn);
}
public MdbResult QuerySQL(String strQuery)
{
try{
MdbResult mresult=new MdbResult();
SelectResult result=null;
SelectStatement sqlStatement = new SelectStatement();
sqlStatement.setConnection(connBean);
StatementMetaData metaData = sqlStatement.getMetaData();
metaData.setSQL(strQuery);
int rownum=getMaxRowCount();
if(rownum>0){
sqlStatement.setMaximumRows(rownum);
}
sqlStatement.execute();
result = sqlStatement.getResult();
mresult.rs=result;
tfmetaData=metaData;
finally{
result.close();
result=null;
sqlStatement.close();
sqlStatement=null;
}
return mresult;
}
调用例子:
public void performTask(
javax.servlet.http.HttpServletRequest req,
javax.servlet.http.HttpServletResponse res)
{
com.wf.db.conpool db = new com.wf.db.conpool();
Connection conn = null;
try
{
com.wf.db.MdbResult rs = new com.wf.db.MdbResult();
conn = ds.getConnection('aa', 'aa');
if (db.GetDBConnection(conn) == false)
{
errstr =
errstr + "Connection To Database Error:" + db.ErrorInfo + db.test + "<br>";
}
else
{
sql = "select * from dic_dept where groupname not like '%*%'";
com.wf.db.MdbResult dicDept = new com.wf.db.MdbResult();
dicDept = db.QuerySQL(sql);
finally
{
db.disconnect();
conn=null;
}
}
 
dicDept = db.QuerySQL(sql);
打开时没有游标和方式,请在QuerySQL类中定义。
 
游标打开太多,大部分情况是由于Statement或PreparedStatement没有执行close()。
SelectStatement 是什么东东?你有最终调用stmt.close()或pstmt.close()吗?
 
SelectStatement说明:(使用的是IBMvaj3.5自带的JAVABEAN:com.ibm.db)
大致如下:
public class SelectStatement extends com.ibm.db.Statement implements com.ibm.db.DatabaseConnectionBeforeListener, com.ibm.db.DatabaseConnectionAfterListener {
protected boolean fieldLockRows;
protected int fieldMaximumPacketsInCache;
private com.ibm.db.SelectResult fieldResult;
protected int fieldMaximumRows;
protected int fieldPacketSize;
protected boolean fieldFillCacheOnExecute;
protected boolean fieldForceSearchedUpdate;
protected boolean forVAJavaSelect;
protected boolean largeResultSetScrollingEnabled;
protected transient boolean executing;
protected transient boolean firstFirstRow;
static final long serialVersionUID;
private static final java.lang.String copyright;
}
public abstract class Statement implements java.io.Serializable {
protected com.ibm.db.DatabaseConnection fieldConnection;
protected boolean fieldExecuted;
protected com.ibm.db.StatementMetaData fieldMetaData;
protected boolean fieldReadOnly;
protected boolean fieldDistinctTypesEnabled;
protected int fieldTimeout;
protected boolean fieldValidateLOBs;
protected com.ibm.db.base.DatabaseRow parameters;
protected transient com.ibm.db.base.DatabaseResultTable rt;
protected transient boolean executingSQL;
protected transient java.beans.PropertyChangeSupport propertyChange;
protected transient com.ibm.db.StatementBeforeListener aStatementBeforeListener;
protected transient com.ibm.db.StatementAfterListener aStatementAfterListener;
static final long serialVersionUID;
private static final java.lang.String copyright;
static java.lang.Class class$array1$$byte;
static java.lang.Class class$java$lang$Short;
static java.lang.Class class$java$sql$Time;
static java.lang.Class class$java$lang$String;
static java.lang.Class class$java$lang$Float;
static java.lang.Class class$java$sql$Timestamp;
static java.lang.Class class$java$lang$Double;
static java.lang.Class class$java$lang$Boolean;
static java.lang.Class class$java$sql$Date;
static java.lang.Class class$java$lang$Long;
static java.lang.Class class$java$sql$Clob;
static java.lang.Class class$java$lang$Integer;
static java.lang.Class class$java$io$InputStream;
static java.lang.Class class$java$math$BigDecimal;
}
 
IBM的select statement最好不要用。有问题。我记得他是没有close方法的。
你应该用标准的jdbc包里面的statement.
 
select statement有close的
原代码如下:
public void close()
throws com.ibm.db.DataException
{
fireAboutToClose(new DataEvent(this));
closeInternal(false);
fireClosed(new DataEvent(this));
}
protected void fireAboutToClose(DataEvent dataevent)
{
if(super.aStatementBeforeListener == null)
{
return;
} else
{
super.aStatementBeforeListener.aboutToClose(dataevent);
return;
}
}

protected void closeInternal(boolean flag)
throws com.ibm.db.DataException
{
SelectResult selectresult = getResult();
if(selectresult != null)
selectresult.closeInternal(flag);
try
{
if(super.rt != null)
super.rt.closeStatement();
}
catch(SQLException sqlexception)
{
if(flag)
Utilities.logSQLException(sqlexception);
else
Statement.handleSQLException(sqlexception);
}
finally
{
super.rt = null;
}
}

protected void fireClosed(DataEvent dataevent)
{
if(super.aStatementAfterListener == null)
{
return;
} else
{
super.aStatementAfterListener.closed(dataevent);
return;
}
}
protected void disconnect()
{
if(getResult() != null)
getResult().disconnect();
//类SelectResult中的方法
super.rt = null;
}
类selectresult中的方法
protected void closeInternal(boolean flag)
throws com.ibm.db.DataException
{
if(!flag)
updateRowBeforeLeaving();
if(statement.getConnection() == null || !statement.getConnection().isConnected())
statement.disconnect();
else
try
{
if(super.rt != null)
super.rt.close();
}
catch(SQLException sqlexception)
{
if(flag)
Utilities.logSQLException(sqlexception);
else
StatementResult.handleSQLException(sqlexception);
}
finally
{
moreRows = false;
previousRows = false;
super.rt = null;
}
}
类SelectResult中的方法
protected void disconnect()
{
super.rt = null;
moreRows = false;
previousRows = false;
singleRowResult = null;
}
 
还是用自己写的connection pool好
 
多人接受答案了。
 
后退
顶部