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



我在截断模式中的所有表时遇到此异常
我在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中的代码或架构配置有什么问题?我该如何解决这个问题?

如果你在getAllTableNames生成的List上迭代,并在一个紧密的循环中调用truncateTable,那么finally块中的free调用可能会被延迟并堆积到无法为下一次迭代快速清除的程度,因为你只知道finally会在某个时候被调用,不一定是在控制权返回给调用者之前。

模式大小会对此产生影响,因此小模式成功而大模式失败可能是有道理的。如果发生了这种情况,那么您应该在try中以及在finally:中调用free

    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块中的检查可能是冗余的,但如果没有它,则如果没有SQLExceptionfree将被调用两次。

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

相关内容

最新更新