jdbc 查询5万条数据出现 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdbc 查询5万条数据出现 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数相关的知识,希望对你有一定的参考价值。

我使用jdbc 查询5万条数据 在循环处理结果集处理到48855条的时候报出的异常是
java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误ORA-01000: 超出打开游标的最大数ORA-00604: 递归 SQL 级别 1 出现错误ORA-01000: 超出打开游标的最大数ORA-01000: 超出打开游标的最大数
我的代码是:
try conn = DBUtil.getConnection1(); String sql = "select distinct tb.user_id, wmsys.wm_concat (tb.resources_id)over(partition BY tb.user_id,tb.cdate order by tb.cdate ) as result,tb.cdate from (select t.user_id,t.resources_id,to_char(t.create_time ,'yyyy-mm-dd') as cdate from SINO_USER_BEHAVIOR2 t where t.visit_long>=0 order by t.create_time desc) tb order by tb.cdate desc"; pre = conn.prepareStatement(sql); rs = pre.executeQuery(); while (rs.next()) UserSequence usqu = new UserSequence(); usqu.setUserId(rs.getInt("user_id")); usqu.setUserSequence(rs.getString("result")); usqu.setData(rs.getString("cdate")); lst.add(usqu); catch (Exception e) e.printStackTrace(); finally

参考技术A 就这段代码本身来说没啥问题,只是要在finally里加上 pre.close()
代码不完整,没办法判断
只能建议你使用select * from v$open_cursor查看当前打开了哪些游标
在循环过程中创建Statement后一定要及时关闭,否则很容易就游标超出了追问

我在finally DBUtil.close(rs); DBUtil.close(stat);DBUtil.close(conn);释放了资源了
就是在向list里面保存实体类的时候保存到48855条记录时候出现的游标
超出打开游标的最大数,是不是jdbc本身查询大数据量导致的啊

追答

数据量大跟游标数没关系,简单一点,你可以理解为打开一个ResultSet就会打开一个游标,就跟你打开一个文件就占用一个句柄一样
如果你不知道怎么检查代码,那就select * from v$open_cursor where user_name=用户名,看看哪些语句占用了游标,然后再从代码里相应ResultSet或Statement有没有关闭

参考技术B 出现ORA-01000错误基本都是有程序没关闭游标,多出现于java程序使用连接池连接数据库的情况下,打开了statement没关闭就把连接放回了连接池或者循环打开statement对象而不关闭。
你的这段代码并无问题,建议检查一下其他地方,有没有上面说的情况。追问

我没有使用连接池 查询什么都没有问题 就是在处理结果集的时候处理到48855条的时候出的问题,而且我的finally中也finally DBUtil.close(pre); DBUtil.close(stat); DBUtil.close(conn);
难道只有改变数据库游标数量这一个办法了吗???

追答

恐怕改游标数量都不一定能解决问题。不过你可以试试。你先看看打开了哪些游标:
select * from v$open_cursor

另外还可以尝试select的时候做分页,将每页数量减少,看能否绕过这个问题。

追问

使用select * from v$open_cursor以后看到了这些:

追答

就只有这几条吗?应该有很多条吧。你重点关注SID,User_name和SQL_Text这三个字段

本回答被提问者和网友采纳

jdbc查询数据库报:java.sql.SQLException: ORA-01006: 绑定变量不存在

错误信息如下:
java.sql.SQLException: ORA-01006: 绑定变量不存在
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:543)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1451)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:651)
at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2117)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2331)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:422)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:366)

代码如下:
/**
* 按条件查询
* @param um
* @return
*/
public ArrayList getUserByCondithion(UserModel um)
ArrayList list = new ArrayList();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
conn = JdbcConn.getConn();
String sql = "select uuid,name,age from tbl_user where 1=1";
pstmt = conn.prepareStatement(sql);
sql = getSql(sql, um);
setSqlValue(pstmt,um);
rs = pstmt.executeQuery();
list = this.rs2Model(rs);
return list;
catch(Exception err)
err.printStackTrace();
finally
try
rs.close();
pstmt.close();
conn.close();
catch (SQLException e)
e.printStackTrace();


return null;


/**
* 按条件查询sql
* @param sql
* @param um
* @return
*/
private String getSql(String sql, UserModel um)
if(um.getUuid() != null && um.getUuid().length() > 0)
sql += " and uuid=? ";

if(um.getName() != null && um.getName().length() > 0)
sql += " and name=? ";

if(um.getAge() != null && um.getAge().length() > 0)
sql += " and age=? ";

return sql;


/**
* 设置sql位置
* @param pstmt
* @param um
* @throws SQLException
* @throws SQLException
*/
private void setSqlValue(PreparedStatement pstmt,UserModel um) throws SQLException
int i = 1;
if(um.getUuid() != null && um.getUuid().trim().length() > 0)
pstmt.setString(i, um.getUuid());
i++;

if(um.getName() != null && um.getName().trim().length() > 0)
pstmt.setString(i, um.getName());
i++;

if(um.getAge() != null && um.getAge().trim().length() > 0)
pstmt.setString(i, um.getAge());
i++;




查询总报“绑定变量不存在”,我的建表语句是:
-- Create table
create table TBL_USER
(
UUID VARCHAR2(10),
NAME VARCHAR2(10),
AGE VARCHAR2(20)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64
next 1
minextents 1
maxextents unlimited
);

执行setSqlValue(pstmt,um)方法时pstmt.setString(i, um.getUuid())这个um.getUuid()是有值的,但到了rs = pstmt.executeQuery()时rs是null,请高手看看这个错是什么原因造成的,非常感谢!

参考技术A setSqlValue方法为什么返回是void呢,你试试看把传入的pstmt返回回去,在主函数处接收返回的pstmt,就解决了!追问

弱弱地问一下,如果setSqlValue返回pstmt的话,主函数处应该怎么写啊?

追答

setSqlValue方法修改为:
private PreparedStatement setSqlValue(PreparedStatement pstmt,UserModel um) throws SQLException

setSqlValue(pstmt,um);处修改为:
pstmt = setSqlValue(pstmt,um);

追问

改成这样之后报:java.lang.NullPointerException
我也认为是这个setSqlValue(PreparedStatement pstmt,UserModel um)方法的问题,pstmt.setString(i, um.getUuid())是可以取到值的,但最后传进去的sql等号后面没有值

追答

你是用单步调试看的吧?PreparedStatement 中的sql语句是不可见的
另外
pstmt = conn.prepareStatement(sql);
sql = getSql(sql, um);
此处的顺序有问题,你需要先getSql,再创建PreparedStatement ,调整为:
sql = getSql(sql, um);
pstmt = conn.prepareStatement(sql);

本回答被提问者采纳

以上是关于jdbc 查询5万条数据出现 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数的主要内容,如果未能解决你的问题,请参考以下文章

oracle 表删除出错 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01426: 数字溢出

ORA-00604: 递归 SQL 级别 1 出现错误和ORA-00942: 表或视图不存在 一起出现怎么解决

怎么处理ora-00604

java开发---关于ORA00604和ORA12705

java.sql.BatchUpdateException: ORA-00604: error occurred at recursive SQL level 1

java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01003: 语句未进行语法分析