You need to enable JavaScript to run this app. Go标准库database/sql中Rows.Err()工作机制及异常问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Go标准库database/sql中Rows.Err()工作机制及异常问题咨询

Rows.Err()的预期工作逻辑

Rows.Err()的设计目标是捕获迭代过程中数据库驱动/底层IO层面产生的用户不可控错误,仅包含以下几类错误:

  • rows.Next()执行时遇到的数据库连接中断、结果集传输错误、底层协议解析错误
  • 迭代未读完所有行就终止时,剩余行数据传输过程中产生的错误
  • 显式/隐式调用Close()释放资源时产生的底层错误

官方给出的方法说明如下:

Err返回迭代过程中遇到的错误,可在显式或隐式调用Close后调用。

你的理解偏差

你错误地认为Scan()返回的所有错误都会被Rows.Err()捕获,实际上这两类错误的产生场景完全不同:
Scan()返回的错误分为两类:

  1. 底层读取行数据产生的错误:这类错误会被同步写入Rows的err字段,可以通过Rows.Err()获取
  2. 用户使用层面的校验错误:比如参数数量不匹配、类型转换失败这类由Scan()方法主动校验返回的错误,不属于底层迭代错误范畴,不会被记录到Rows的err字段中,自然无法通过Rows.Err()获取。你测试时触发的sql: expected 6 destination arguments in Scan, not 5就属于这类错误。

标准错误处理写法

实际开发中需要同时处理Scan()返回的使用错误和Rows.Err()返回的底层错误:

var err error
for rows.Next() {
    t := someStruct{}
    err = rows.Scan(&t.Field1, &t.Field2, &t.Field3, &t.Field4, &t.Field5, &t.Field6)
    if err != nil {
        // 优先处理Scan层面的错误
        log.Debug(err)
        break
    }
    templates = append(templates, &t)
}
// 显式关闭结果集
rows.Close()
// 再判断底层迭代错误
if rowsErr := rows.Err(); rowsErr != nil {
    log.Error(rowsErr)
}

内容的提问来源于stack exchange,提问作者Aditya Kumar Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 04:09:02