使用更优雅的断言来代替 strings.Contains
。
处理 MySQL Duplicate 错误是比较基础的内容,但目前网上的资料不是很全面,对入门同学有门槛。
日常 Go 开发过程中经常会操作数据库,使用 INSERT
操作时可能会遇到主键或者唯一索引发生冲突的情况,日志输出的内容如下所示。
Error 1062: Duplicate entry '%s' for key %d
正确处理方式
断言 Error
接口为 mysql.MySQLError
类型,随后判断 Number 字段值为 1062
即可进行特殊处理。
import (
"database/sql"
"os"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, _ := sql.Open("mysql", os.Getenv("DSN"))
_, err := db.Exec("INSERT INTO test_table(id) VALUES (1)")
if err != nil {
// make sure err is a mysql.MySQLError.
if errMySQL, ok := err.(*mysql.MySQLError); ok {
switch errMySQL.Number {
case 1062:
// TODO handle Error 1062: Duplicate entry '%s' for key %d
}
}
}
}
原理
日志输出的内容是 Go 基本库 Error
接口的 Error
方法结果,如果我们使用的是 go-sql-driver
作为 Driver
,那么 Error
接口的实现是 go-sql-driver
内的 MySQLError
结构体。
代码位置在 go-sql-driver/mysql/blob/master/errors.go#L58
,源码如下所示。
// MySQLError is an error type which represents a single MySQL error
type MySQLError struct {
Number uint16
Message string
}
func (me *MySQLError) Error() string {
return fmt.Sprintf("Error %d: %s", me.Number, me.Message)
}
根据上述原理进行类推,我们可以根据全部 MySQL 错误代码进行处理。
参考资料
关于 MySQL 错误,您可以查阅 MySQL 官方文档 - Chapter 2 Server Error Message Reference。