如何在Go database/sql中使用rows.NextResultSet()及返回false问题排查
多结果集返回异常排查解决方案
核心排查方向
- 检查数据库连接串配置:
denisenkom/go-mssqldb驱动默认未开启多结果集支持,必须在DSN连接参数中添加multipleActiveResultSets=true,否则驱动只会返回第一个结果集,后续结果集会被直接丢弃,导致rows.NextResultSet()直接返回false。 - 补充结果集遍历后的错误检查:你当前代码在第一个
for rows.Next()循环结束后,没有调用rows.Err()判断是否存在读取错误。如果第一个结果集读取过程中已经发生异常,会直接中断后续结果集的返回,此时NextResultSet必然返回false。 - 验证SQL语句合法性:
- 多段SQL中不能包含
GO这类SQL Server客户端专用的批处理指令,该类指令无法被驱动直接识别,会导致后续SQL被截断不执行 - 确认每一段需要返回结果集的SQL为会产生行数据的语句(如SELECT查询、带OUTPUT子句的DML语句),普通无返回的INSERT/UPDATE/DELETE不会生成结果集
- 多段SQL中不能包含
- 升级驱动版本:部分旧版本的
denisenkom/go-mssqldb存在多结果集处理的已知bug,可执行go get github.com/denisenkom/go-mssqldb@latest升级到最新稳定版后重试。
修正后的代码示例
// DSN参考示例:sqlserver://username:password@host:port?database=dbname&multipleActiveResultSets=true rows, err := db.Query(` SELECT col1,col2 FROM table1; SELECT col1,col2 FROM table2; SELECT col1,col2 FROM table3; `) if err != nil { log.Fatalf("查询执行失败: %v", err) } defer rows.Close() // 处理第一个结果集 for rows.Next() { var col1, col2 string if err := rows.Scan(&col1, &col2); err != nil { log.Fatalf("数据扫描失败: %v", err) } // 业务逻辑处理 } // 检查第一个结果集遍历是否存在错误 if err = rows.Err(); err != nil { log.Fatalf("第一个结果集读取异常: %v", err) } // 切换第二个结果集 if !rows.NextResultSet() { // 先检查切换过程是否有报错 if err = rows.Err(); err != nil { log.Fatalf("结果集切换失败: %v", err) } log.Println("Expected another result set.") return } // 处理第二个结果集 for rows.Next() { var col1, col2 string if err := rows.Scan(&col1, &col2); err != nil { log.Fatalf("第二结果集数据扫描失败: %v", err) } // 第二结果集业务逻辑处理 } if err = rows.Err(); err != nil { log.Fatalf("第二个结果集读取异常: %v", err) }
内容的提问来源于stack exchange,提问作者calvinsomething
相关产品推荐
相关产品推荐

