如何在Go中执行多SQL语句查询并获取多个结果行集
问题原因
- 需先开启数据库驱动的多语句执行支持:以常用的
go-sql-driver/mysql驱动为例,默认关闭多语句执行能力,需要在连接DSN中添加multiStatements=true参数,才会返回多条语句对应的多结果集。 - 方法调用逻辑错误:
Query()返回的sql.Rows对象的Next()方法是用来迭代SELECT类语句返回的数据行的,UPDATE语句没有数据行返回,所以直接调用Next()会返回false,但你不需要读取行数据,只需要获取每个结果集对应的执行影响行数即可。
正确实现代码
tx, err := conn.StartTransaction(ctx) if err != nil { fmt.Println("事务开启失败:", err.Error()) return } defer tx.Rollback() sqlstr := `update table1 set user_name = "d1" where user_id = 1; update table1 set user_name = "d2" where user_id = 2;` res, err := tx.Query(sqlstr) if err != nil { fmt.Println("SQL执行失败:", err.Error()) return } defer res.Close() // 遍历所有结果集 for { // 先判断当前结果集是否有效 if !res.Next() { // 检查结果集读取错误 if err = res.Err(); err != nil { fmt.Println("结果集读取错误:", err.Error()) return } // 没有下一个结果集就退出 if !res.NextResultSet() { break } continue } // 获取当前语句的影响行数 rowCnt, err := res.RowsAffected() if err != nil { fmt.Println("获取影响行数失败:", err.Error()) return } fmt.Println("当前语句影响行数:", rowCnt) // 检查是否还有下一个结果集 if !res.NextResultSet() { break } } // 最后提交事务 if err = tx.Commit(); err != nil { fmt.Println("事务提交失败:", err.Error()) return }
注意事项
- 多语句执行存在较高的SQL注入风险,如果你无法完全控制传入的SQL内容,不推荐使用该方案,尽量拆分单条语句执行更安全。
- 不同数据库的驱动对多语句的支持逻辑存在差异,若使用非MySQL数据库,需参考对应驱动的官方文档调整适配。
内容的提问来源于stack exchange,提问作者dlwlrma
相关产品推荐
相关产品推荐

