golang sql 插入时报错 Error 1292: Incorrect datetime value: '' for column at row 1

更新日期: 2020-05-27 阅读次数: 5262 字数: 304 分类: golang

在解析百度统计实时访客 csv 文件时,会遇到上次访问时间为空的情况。

pre_access_at := ""
if strings.HasPrefix(record[13], "2") {
    pre_access_at = record[13]
}

这样在执行 SQL insert 操作时,会报错:

Error 1292: Incorrect datetime value: '' for column 'pre_access_at' at row 1

而 golang 中 string 类型并不能被赋值为 nil。

即便使用 time.Time, 也会因为 time.Time 默认值是 '0000-00-00',也是 incorrect datetime value。

golang 官方在 1.13 版本之后增加了 sql.NullTime 类型以解决此问题。

mysql.NullTime is depricated https://github.com/go-sql-driver/mysql/issues/960 database/sql will have a NullTime type from Go1.13 onward, which should be used instead https://github.com/golang/go/issues/30305

参考:

https://golang.org/pkg/database/sql/#NullTime

NullTime represents a time.Time that may be null. NullTime implements the Scanner interface so it can be used as a scan destination, similar to NullString.

type NullTime struct {
    Time  time.Time
    Valid bool // Valid is true if Time is not NULL
}

类似的类型还有 sql.NullString,因为 golang 中 string 也不能赋值为 nil。

由于我不会 string 到 time.Time 的转换,所以想直接使用 sql.NullString 来插入 MySQL datetime 字段应该也可以。

参考:

https://stackoverflow.com/questions/40266633/golang-insert-null-into-sql-instead-of-empty-string

func NewNullString(s string) sql.NullString {
    if len(s) == 0 {
        return sql.NullString{}
    }
    return sql.NullString{
         String: s,
         Valid: true,
    }
}

这样就可以在 sql 参数中使用 NewNullString(pre_access_at) 来做 nil 兼容处理了。

参考

  • https://barbery.me/post/2018-06-11-fix-go-null-time/
  • https://medium.com/aubergine-solutions/how-i-handled-null-possible-values-from-database-rows-in-golang-521fb0ee267

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式