Operation not allowed after ResultSet closed,ResultSet is from UPDATE. No Data和Column 'xxx' not f...

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实例

解决方法:

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

  2. 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实例。

  3. 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语句和预编译后的sql语句不相同

  1. 若是在JDBC工具类中将ConnectionPreparedStatementResultSet定义成全局静态变量,则要考虑线程安全问题,可能会出现上述2的问题,将可能出现线程安全的地方同步即可。

总结:

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

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

报错原因:

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

解决思路:

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

解决方法:

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

3. Column 'xxx' not found的解决方法

报错原因:

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

解决思路:

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

解决方法:

  1. 检查SQL语句是否正确,比如select name from user;,在Java中却是rs.getString("password");,或者是select nam from user;,在Java中rs.getString("name");认真检查一下修改即可。
  2. debug进入PreparedStatement或Statement,或控制台打印PreparedStatementStatement编译后的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关键字进行同步。

  1. 若是在JDBC工具类中将ConnectionPreparedStatementResultSet定义成全局静态变量,则要考虑线程安全问题,将可能出现线程安全的地方同步即可。

总结

  • 先检查SQL语句是否正确
  • 理清链路 加载JDBC驱动 --> Connection --> PreparedStatement --> ResultSet ,先想到最有可能出错的地方,打断点debug进去或控制台打印可能出错的变量
  • 若没有使用数据库连接池,如果JDBC工具类中有静态变量,须考虑线程安全问题,能用数据库连接池尽量使用数据库连接池
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容

  • 本节介绍Statement接口及其子类PreparedStatement和CallableStatement。 它...
    zlb阅读 1,160评论 0 0
  • JDBC简介 SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。JDBC...
    奋斗的老王阅读 1,515评论 0 51
  • 本人的环境为Myeclipse10、MySQL5.7.15 本文包括:简介JDBC编程步骤打通数据库程序详解—Dr...
    廖少少阅读 3,944评论 7 39
  • 一. Java基础部分.................................................
    wy_sure阅读 3,810评论 0 11
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,509评论 0 4