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; }報錯時截圖:
總結:
- 先查看是否手動調用過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實例的代碼是否有問題,并一級一級往里追原因
解決方法:
3. Column 'xxx' not found的解決方法
報錯原因:
Column 'xxx' not found直譯的意思就是沒有找到xxx這一列,也就是說,查詢的結果中,沒有該字段的列。
解決思路:
- 檢查SQL語句是否正確
- 檢查編譯后的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關鍵字進行同步。
總結
- 先檢查SQL語句是否正確
- 理清鏈路 加載JDBC驅動 --> Connection --> PreparedStatement --> ResultSet ,先想到最有可能出錯的地方,打斷點debug進去或控制臺打印可能出錯的變量
- 若沒有使用數據庫連接池,如果JDBC工具類中有靜態變量,須考慮線程安全問題,能用數據庫連接池盡量使用數據庫連接池
總結
以上是生活随笔為你收集整理的Operation not allowed的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取素材列表返回40004 invali
- 下一篇: 简单理解通大查询下学期课表原理