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

文章目录

    在解析百度统计实时访客 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式