java.sql.SQLException:ORA-01000:截断表时超出了最大打开游标数

时间:2013-07-29 10:07:15

标签: java oracle

我在截断模式中的所有表时遇到此异常 我在我的Java代码中截断3个模式,第一个方法从给定的模式名称获取表名列表,第二个方法执行“TRUNCATE TABLE table_name”查询。
我混淆了我的代码总是成功,同时截断第一和第三个架构。但是在第二个架构上执行时,我得到 ORA-01000 错误 我的截断代码是

    private void truncateTable(Connection conn, String tableName) {
    PreparedStatement ps = null;
    try {
        ps = conn.prepareStatement(Utility.TRUNCATE_TABLE + tableName);
        ps.executeUpdate();
    } catch (SQLException e) {
        log.error("SQLException occured while getting table names from schema", e);
    } finally {
        Utility.free(ps, null, null);
    }
}


    private List<String> getAllTableNames(Connection conn) {
    PreparedStatement ps = null;
    ResultSet rs = null;
    List<String> list = new ArrayList<String>();
    try {
        ps = conn.prepareStatement(Utility.SELECT_ALL_TABLE_NAMES);
        rs = ps.executeQuery();
        while (rs.next()) {
            list.add(rs.getString("TABLE_NAME"));
        }
    } catch (SQLException e) {
        log.error("SQLException occured while getting table names from schema", e);
    } finally {
        Utility.free(ps, rs, null);
    }
    return list;
}

    public static void free(PreparedStatement ps, ResultSet rs, Connection conn) {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
            log.error("Error occurred while closing ResultSet",e);
        }
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) {
            log.error("Error occurred while closing PreparedStatement",e);
        }
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) {
            log.error("Error occurred while closing Connection",e);
        }
    }
}

代码有什么问题,或者是关于Oracle中的架构配置? 我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

如果您正在迭代getAllTableNames生成的列表并在紧急循环中调用truncateTable,那么free块中的finally个来电可能会被延迟并堆叠在某种程度上,它们没有足够快地清除下一次迭代 - 因为你只知道finally将在某个时刻被调用,不一定立即被调用,并且在控制返回给调用者之前。

模式大小会对此产生影响,因此可能有意义的是,小模式成功,大模式失败。如果发生了这种情况,那么您应该在free内以及try内呼叫finally

    private void truncateTable(Connection conn, String tableName) {
    PreparedStatement ps = null;
    try {
        ps = conn.prepareStatement(Utility.TRUNCATE_TABLE + tableName);
        ps.executeUpdate();
        Utility.free(ps, null, null);
        ps = null;
    } catch (SQLException e) {
        log.error("SQLException occured while getting table names from schema", e);
    } finally {
        if (ps != null) {
            Utility.free(ps, null, null);
        }
    }
}

如果Utility.free检查ps是否为空,那么finally块中的检查可能是多余的,但如果没有,free将被调用两次,如果没有SQLException

答案 1 :(得分:0)

检查代码并确保在使用后关闭游标。如果问题仍然存在,请将OPEN_CURSORS设置为更多值。