欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Operation not allowed

发布时间:2023/12/16 编程问答 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Operation not allowed 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1. Operation not allowed after ResultSet closed的解决方法

报错原因:

Operation not allowed after ResultSet closed翻译后的意思是ResultSet关闭后不允许操作,也就是说在ResultSet的实例调用close()方法后,又再次使用了该实例。

解决思路:

  • 查看报错处的ResultSet实例是否已经调用过close()方法关闭
  • 报错处的ResultSet实例是否和其他ResultSet实例来自的是同一个Connection实例,就是说一个Connection实例执行完不同的SQL语句后返回不同的ResultSet实例。查看该Connection实例是否同时执行不同SQL语句返回ResultSet实例

解决方法:

  • 先查看ResultSet实例是否已经调用了close()方法,即rs.close()。

  • 若ResultSet实例并未调用close()方法,则查看生成该ResultSet实例的Connection实例,该Connection实例是否还执行过其他SQL语句。若有则查看该Connection实例是否同时执行了多条SQL语句。若同时执行了多条SQL语句,则需要在获取数据库连接到执行SQL语句的流程加上synchronized关键字让Connection实例在执行某个SQL语句时,不让Connection实例同时执行其他的SQL语句,因为一个Connection实例可以对应多个Statement实例或PreparedStatement实例,但一个Statement实例或PreparedStatement实例只能对应一个ResultSet实例。若同一个Connection实例用同一个Statement实例或PreparedStatement实例执行不同SQL语句,则两个SQL语句生成了一个ResultSet实例。

  • 若ResultSet实例并没有调用了close()方法,但又觉得不是该Connection实例并未执行过多条SQL语句,则debug查看Statement实例或PreparedStatement实例是否同时进入了多条SQL语句,或在控制台中打印Statement实例或PreparedStatement实例执行的SQL语句。

    控制台打印Statement实例或PreparedStatement实例执行的SQL语句代码如下:

    /**** 执行查询的sql语句,并返回结果集* @param sql sql语句* @param objects 替代占位符的数组* @return ResultSet结果集*/ public static ResultSet executeQuery(String sql, Object... objects) {System.out.println("sql ->" + sql);connection = getConnection();System.out.println("connection->" + connection);try {ppstmt = connection.prepareStatement(sql);System.out.println(sql + " ppstm1->" + ppstmt);if (objects != null && objects.length > 0) {for (int i = 0; i < objects.length; i++) {ppstmt.setObject(i + 1, objects[i]);}}rs = ppstmt.executeQuery();System.out.println(sql + " ppstm->" + ppstmt);} catch (SQLException e) {System.out.println("SQL语句错误或参数个数与占位符不一致");e.printStackTrace();return rs;}return rs; }

    报错时截图:

  • 可以看到SQL语句和预编译后的SQ语句不相同
  • 若是在JDBC工具类中将Connection,PreparedStatement或ResultSet定义成全局静态变量,则要考虑线程安全问题,可能会出现上述2的问题,将可能出现线程安全的地方同步即可。
  • 总结:

    • 先查看是否手动调用过ResultSet的close()方法
    • 若没有,则查看ResultSet实例是否只对应一个Statement实例或PreparedStatement实例
    • 若定义了全局静态变量,考虑线程安全问题

    2. ResultSet is from UPDATE. No Data的解决方法

    报错原因:

    ResultSet is from UPDATE. No Data直译后的意思是ResultSet 是来自更新(添加,删除,修改语句)。没有数据。也就是说Result的实例可能是执行增删改的SQL语句(该SQL语句不是查询语句),或者是查询语句但ResultSet 实例调用next()方法后没有数据,即while(rs.next())中的rs没有数据,所以调用next()方法会报错。

    解决思路:

    • 检查SQL语句是否正确
    • 使用execute和getResultSet方法
    • 查看创建ResultSet实例的代码是否有问题,并一级一级往里追原因

    解决方法:

  • 检查SQL语句,只有查询语句执行后才会返回ResultSet
  • 使用execute和getResultSet方法
  • 若SQL语句正确,能在数据库中执行该SQL语句,但Java中却不行,则往上追到PreparedStatement或Statement。debug进入或在控制台打印传入的SQL语句和编译的SQL语句是否相同,若不相同,则是同一时间进入了多条SQL语句,考虑线程安全问题。在需要同步的代码块加上synchronized关键字。
  • 若是在JDBC工具类中将Connection,PreparedStatement或ResultSet定义成全局静态变量,则要考虑线程安全问题,将可能出现线程安全的地方同步即可。
  • 3. Column 'xxx' not found的解决方法

    报错原因:

    Column 'xxx' not found直译的意思就是没有找到xxx这一列,也就是说,查询的结果中,没有该字段的列。

    解决思路:

    • 检查SQL语句是否正确
    • 检查编译后的SQL语句是否和预期的SQL语句相同

    解决方法:

  • 检查SQL语句是否正确,比如select name from user;,在Java中却是rs.getString("password");,或者是select nam from user;,在Java中rs.getString("name");认真检查一下修改即可。
  • debug进入PreparedStatement或Statement,或控制台打印PreparedStatement或Statement编译后的SQL语句和传入的SQL语句是否相同
  • 报错截图:

    上图可知传入的SQL语句和编译后的SQL语句不同

    再看下报错处的代码

    /*** 查找所有学生** @return 学生集合*/ @Override public ArrayList<Student> selectAllStudent() {String sql = "SELECT * FROM db_studentinfo";ArrayList<Student> studentList = null;ResultSet rs = JDBCUtil.executeQuery(sql);try {studentList = new ArrayList<Student>();while (rs.next()) {studentList.add(setStudent(rs));}} catch (SQLException e) {e.printStackTrace();return studentList;} finally {JDBCUtil.closeDB();}return studentList; }// 将查询的结果集放入学生对象中 private Student setStudent(ResultSet rs) {Student student = null;try {student = new Student();student.setStudentNum(rs.getInt("学生学号"));student.setStudentName(rs.getString("学生姓名"));student.setGrade(rs.getString("年级"));student.setStudentClass(rs.getString("班级"));student.setSex(rs.getString("性别"));student.setAge(rs.getInt("年龄"));student.setAddress(rs.getString("家庭住址"));student.setPhone(rs.getString("联系电话"));} catch (SQLException e) {e.printStackTrace();return student;}return student; }

    因为此时是两条SQL语句同时进入PreparedStatement实例中,所以虽然传入的是正确的SQL语句,但是由于其他的SQL语句也进入了,所以导致查询返回的结果集并不是我们一开始传入的SQL语句的结果集,故会报

    Column '学生学号' not found.的错误。从线程安全方面排查原因,比如在可能导致两条SQL语句同时进入PreparedStatement实例的代码块中加synchronize关键字进行同步。

  • 若是在JDBC工具类中将Connection,PreparedStatement或ResultSet定义成全局静态变量,则要考虑线程安全问题,将可能出现线程安全的地方同步即可。
  • 总结

    • 先检查SQL语句是否正确
    • 理清链路 加载JDBC驱动 --> Connection --> PreparedStatement --> ResultSet ,先想到最有可能出错的地方,打断点debug进去或控制台打印可能出错的变量
    • 若没有使用数据库连接池,如果JDBC工具类中有静态变量,须考虑线程安全问题,能用数据库连接池尽量使用数据库连接池

    总结

    以上是生活随笔为你收集整理的Operation not allowed的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。