Operation not allowed
1. Operation not allowed after ResultSet closed的解決方法
報(bào)錯(cuò)原因:
Operation not allowed after ResultSet closed翻譯后的意思是ResultSet關(guān)閉后不允許操作,也就是說在ResultSet的實(shí)例調(diào)用close()方法后,又再次使用了該實(shí)例。
解決思路:
- 查看報(bào)錯(cuò)處的ResultSet實(shí)例是否已經(jīng)調(diào)用過close()方法關(guān)閉
- 報(bào)錯(cuò)處的ResultSet實(shí)例是否和其他ResultSet實(shí)例來自的是同一個(gè)Connection實(shí)例,就是說一個(gè)Connection實(shí)例執(zhí)行完不同的SQL語(yǔ)句后返回不同的ResultSet實(shí)例。查看該Connection實(shí)例是否同時(shí)執(zhí)行不同SQL語(yǔ)句返回ResultSet實(shí)例
解決方法:
先查看ResultSet實(shí)例是否已經(jīng)調(diào)用了close()方法,即rs.close()。
若ResultSet實(shí)例并未調(diào)用close()方法,則查看生成該ResultSet實(shí)例的Connection實(shí)例,該Connection實(shí)例是否還執(zhí)行過其他SQL語(yǔ)句。若有則查看該Connection實(shí)例是否同時(shí)執(zhí)行了多條SQL語(yǔ)句。若同時(shí)執(zhí)行了多條SQL語(yǔ)句,則需要在獲取數(shù)據(jù)庫(kù)連接到執(zhí)行SQL語(yǔ)句的流程加上synchronized關(guān)鍵字讓Connection實(shí)例在執(zhí)行某個(gè)SQL語(yǔ)句時(shí),不讓Connection實(shí)例同時(shí)執(zhí)行其他的SQL語(yǔ)句,因?yàn)橐粋€(gè)Connection實(shí)例可以對(duì)應(yīng)多個(gè)Statement實(shí)例或PreparedStatement實(shí)例,但一個(gè)Statement實(shí)例或PreparedStatement實(shí)例只能對(duì)應(yīng)一個(gè)ResultSet實(shí)例。若同一個(gè)Connection實(shí)例用同一個(gè)Statement實(shí)例或PreparedStatement實(shí)例執(zhí)行不同SQL語(yǔ)句,則兩個(gè)SQL語(yǔ)句生成了一個(gè)ResultSet實(shí)例。
若ResultSet實(shí)例并沒有調(diào)用了close()方法,但又覺得不是該Connection實(shí)例并未執(zhí)行過多條SQL語(yǔ)句,則debug查看Statement實(shí)例或PreparedStatement實(shí)例是否同時(shí)進(jìn)入了多條SQL語(yǔ)句,或在控制臺(tái)中打印Statement實(shí)例或PreparedStatement實(shí)例執(zhí)行的SQL語(yǔ)句。
控制臺(tái)打印Statement實(shí)例或PreparedStatement實(shí)例執(zhí)行的SQL語(yǔ)句代碼如下:
/**** 執(zhí)行查詢的sql語(yǔ)句,并返回結(jié)果集* @param sql sql語(yǔ)句* @param objects 替代占位符的數(shù)組* @return ResultSet結(jié)果集*/ 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語(yǔ)句錯(cuò)誤或參數(shù)個(gè)數(shù)與占位符不一致");e.printStackTrace();return rs;}return rs; }報(bào)錯(cuò)時(shí)截圖:
總結(jié):
- 先查看是否手動(dòng)調(diào)用過ResultSet的close()方法
- 若沒有,則查看ResultSet實(shí)例是否只對(duì)應(yīng)一個(gè)Statement實(shí)例或PreparedStatement實(shí)例
- 若定義了全局靜態(tài)變量,考慮線程安全問題
2. ResultSet is from UPDATE. No Data的解決方法
報(bào)錯(cuò)原因:
ResultSet is from UPDATE. No Data直譯后的意思是ResultSet 是來自更新(添加,刪除,修改語(yǔ)句)。沒有數(shù)據(jù)。也就是說Result的實(shí)例可能是執(zhí)行增刪改的SQL語(yǔ)句(該SQL語(yǔ)句不是查詢語(yǔ)句),或者是查詢語(yǔ)句但ResultSet 實(shí)例調(diào)用next()方法后沒有數(shù)據(jù),即while(rs.next())中的rs沒有數(shù)據(jù),所以調(diào)用next()方法會(huì)報(bào)錯(cuò)。
解決思路:
- 檢查SQL語(yǔ)句是否正確
- 使用execute和getResultSet方法
- 查看創(chuàng)建ResultSet實(shí)例的代碼是否有問題,并一級(jí)一級(jí)往里追原因
解決方法:
3. Column 'xxx' not found的解決方法
報(bào)錯(cuò)原因:
Column 'xxx' not found直譯的意思就是沒有找到xxx這一列,也就是說,查詢的結(jié)果中,沒有該字段的列。
解決思路:
- 檢查SQL語(yǔ)句是否正確
- 檢查編譯后的SQL語(yǔ)句是否和預(yù)期的SQL語(yǔ)句相同
解決方法:
報(bào)錯(cuò)截圖:
上圖可知傳入的SQL語(yǔ)句和編譯后的SQL語(yǔ)句不同
再看下報(bào)錯(cuò)處的代碼
/*** 查找所有學(xué)生** @return 學(xué)生集合*/ @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; }// 將查詢的結(jié)果集放入學(xué)生對(duì)象中 private Student setStudent(ResultSet rs) {Student student = null;try {student = new Student();student.setStudentNum(rs.getInt("學(xué)生學(xué)號(hào)"));student.setStudentName(rs.getString("學(xué)生姓名"));student.setGrade(rs.getString("年級(jí)"));student.setStudentClass(rs.getString("班級(jí)"));student.setSex(rs.getString("性別"));student.setAge(rs.getInt("年齡"));student.setAddress(rs.getString("家庭住址"));student.setPhone(rs.getString("聯(lián)系電話"));} catch (SQLException e) {e.printStackTrace();return student;}return student; }因?yàn)榇藭r(shí)是兩條SQL語(yǔ)句同時(shí)進(jìn)入PreparedStatement實(shí)例中,所以雖然傳入的是正確的SQL語(yǔ)句,但是由于其他的SQL語(yǔ)句也進(jìn)入了,所以導(dǎo)致查詢返回的結(jié)果集并不是我們一開始傳入的SQL語(yǔ)句的結(jié)果集,故會(huì)報(bào)
Column '學(xué)生學(xué)號(hào)' not found.的錯(cuò)誤。從線程安全方面排查原因,比如在可能導(dǎo)致兩條SQL語(yǔ)句同時(shí)進(jìn)入PreparedStatement實(shí)例的代碼塊中加synchronize關(guān)鍵字進(jìn)行同步。
總結(jié)
- 先檢查SQL語(yǔ)句是否正確
- 理清鏈路 加載JDBC驅(qū)動(dòng) --> Connection --> PreparedStatement --> ResultSet ,先想到最有可能出錯(cuò)的地方,打斷點(diǎn)debug進(jìn)去或控制臺(tái)打印可能出錯(cuò)的變量
- 若沒有使用數(shù)據(jù)庫(kù)連接池,如果JDBC工具類中有靜態(tài)變量,須考慮線程安全問題,能用數(shù)據(jù)庫(kù)連接池盡量使用數(shù)據(jù)庫(kù)連接池
總結(jié)
以上是生活随笔為你收集整理的Operation not allowed的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取素材列表返回40004 invali
- 下一篇: 简单理解通大查询下学期课表原理