Golang 用go-sql-driver 调用MySQL存储过程时的问题排查
2023-09-11 14:15:05 时间
今天在用go-sql-driver做MySQL driver调用MySQL的存储过程时遇到一个罕见的报错。本文对这个错误及其解做一个简单的总结。
1 问题描述
按照go中sql包提供的接口,应用层代码调用MySQL存储过程的代码一般如下所示:
result, err := dbh.Exec("call some_procedure(?, ?)", param1, param2) if err != nil { // error handler } // using result...
但是在实际执行的时候err不为nil,err的值是MySQL返回给driver的出错信息:
Error 1312: PROCEDURE tcheck_db.update_vs_available can't return a result set in the given context
2 问题原因
出现这个问题的原因是在调用存储过程时,MySQL希望客户端的连接类型是multi-statement模式,但是go-sql-driver这个包目前没有设置这个连接模式,所以MySQL给返回了1中的错误。
实际上,在用go-sql-driver时,除了无法调用存储过程外,还存在一些其他的限制,这些限制可以在go-database-sql-surprises中看到。
go-sql-driver的讨论区也有人报出了这个问题,见这里。
3 问题解法
既然找到了病因,那就要对症下药,能想到的办法就是将go-sql-driver连接MySQL时的connection mode设置为multi-statement。方法是:
1) go get github.com/go-sql-driver/mysql 下载依赖包
2)编辑文件src/github.com/go-sql-driver/mysql/packets.go文件,在函数writeAuthPacket(cipher []byte) (大约在210行)的客户端标志位处添加下面两个标志:
clientMultiStatements 和 clientMultiResults
添加后的代码如下:
func (mc *mysqlConn) writeAuthPacket(cipher []byte) error { // Adjust client flags based on server support clientFlags := clientProtocol41 | clientSecureConn | clientLongPassword | clientTransactions | clientLocalFiles | clientMultiStatements | // 添加这行 clientMultiResults | //再添加这行 mc.flags&clientLongFlag if mc.cfg.clientFoundRows { clientFlags |= clientFoundRows } ...
3,rebuild您的依赖go-sql-driver的代码。
OK。经过上面三步修改之后,执行1中的存储过程代码时,就不会报错了。
相关文章
- mysql decode encode 乱码问题
- Mysql授权允许远程访问解决Navicat for MySQL连接mysql提示客户端不支持服务器请求的身份验证协议;考虑升级MySQL客户端
- 【Go命令教程】7. go run
- 【MySql】mysql 字段个数的限制
- [MySQL] Insert mutil rows into table
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
- MYSQL错误解决:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
- MySQL高可用性之Keepalived+Mysql(双主热备)
- MySQL · 8.0新特性· Invisible Index
- MySQL · 答疑解惑 · MySQL 优化器 range 的代价计算
- 【Go语言】【7】GO语言的切片
- 【Go语言】【3】GO语言常量
- 【Go语言】【18】GO语言的select
- 我们可以使用MySQL创建一个具有数字名称的数据库吗?
- MYSQL避免全表扫描__如何查看sql查询是否用到索引(mysql)
- MySQL中OR和AND的区别是什么____MySQL中or与in
- Go Gin框架:连接MySQL数据库
- MySQL server version for the right syntax to use near 'type=InnoDB' at line 1
- 《Mysql技术内幕》读书笔记
- mysql select into outfile默认文件保存路径是C:ProgramDataMySQLMySQL Server 8.0Data
- Groonga开源搜索引擎——列存储做聚合,没有内建分布式,分片和副本是随mysql或者postgreSQL作为存储引擎由MySQL自身来做分片和副本的
- mysql varchar 最大存多少
- 【高可用MySQL解决方案】centos7配置mysql主从复制
- MySQL报错Column count of mysql.user is wrong. Expected 43, found 42. Created with MySQL 50568, now run