golang查询mysql数据库时字段的值为NULL问题

查询数据库时,执行db.Query和Scan,如果遇到值为NULL的字段,就要传入sq.NullString,sql.NullInt32,sql.NullInt64,sql.NullBool,sql.NullTime,sql.NullFloat64等类型以代替原来的string,int,int64,bool,Time,float64等类型。

可以参考源码:

github.com/go-sql-driver/mysql/driver_test.go

func TestNULL(t *testing.T) {
        runTests(t, dsn, func(dbt *DBTest) {
                nullStmt, err := dbt.db.Prepare("SELECT NULL")
                if err != nil {
                        dbt.Fatal(err)
                }
                defer nullStmt.Close()

                nonNullStmt, err := dbt.db.Prepare("SELECT 1")
                if err != nil {
                        dbt.Fatal(err)
                }
                defer nonNullStmt.Close()

                // NullBool
                var nb sql.NullBool
                // Invalid
                if err = nullStmt.QueryRow().Scan(&nb); err != nil {
                        dbt.Fatal(err)
                }
                if nb.Valid {
                        dbt.Error("valid NullBool which should be invalid")
                }
                // Valid
                if err = nonNullStmt.QueryRow().Scan(&nb); err != nil {
                        dbt.Fatal(err)
                }
                if !nb.Valid {
                        dbt.Error("invalid NullBool which should be valid")
                } else if nb.Bool != true {
                        dbt.Errorf("Unexpected NullBool value: %t (should be true)", nb.Bool)
                }

                // NullFloat64
                var nf sql.NullFloat64
                // Invalid
                if err = nullStmt.QueryRow().Scan(&nf); err != nil {
                        dbt.Fatal(err)
                }
                if nf.Valid {
                        dbt.Error("valid NullFloat64 which should be invalid")
                }
                // Valid
                if err = nonNullStmt.QueryRow().Scan(&nf); err != nil {
                        dbt.Fatal(err)
                }
                if !nf.Valid {
                        dbt.Error("invalid NullFloat64 which should be valid")
                } else if nf.Float64 != float64(1) {
                        dbt.Errorf("unexpected NullFloat64 value: %f (should be 1.0)", nf.Float64)
                }

                // NullInt64
                var ni sql.NullInt64
                // Invalid
                if err = nullStmt.QueryRow().Scan(&ni); err != nil {
                        dbt.Fatal(err)
                }
                if ni.Valid {
                        dbt.Error("valid NullInt64 which should be invalid")
                }
                // Valid
                if err = nonNullStmt.QueryRow().Scan(&ni); err != nil {
                        dbt.Fatal(err)
                }
                if !ni.Valid {
                        dbt.Error("invalid NullInt64 which should be valid")
                } else if ni.Int64 != int64(1) {
                        dbt.Errorf("unexpected NullInt64 value: %d (should be 1)", ni.Int64)
                }

                // NullString
                var ns sql.NullString
                // Invalid
                if err = nullStmt.QueryRow().Scan(&ns); err != nil {
                        dbt.Fatal(err)
                }
                if ns.Valid {
                        dbt.Error("valid NullString which should be invalid")
                }
                // Valid
                if err = nonNullStmt.QueryRow().Scan(&ns); err != nil {
                        dbt.Fatal(err)
                }
                if !ns.Valid {
                        dbt.Error("invalid NullString which should be valid")
                } else if ns.String != `1` {
                        dbt.Error("unexpected NullString value:" + ns.String + " (should be `1`)")
                }

                // nil-bytes
                var b []byte
                // Read nil
                if err = nullStmt.QueryRow().Scan(&b); err != nil {
                        dbt.Fatal(err)
                }
                if b != nil {
                        dbt.Error("non-nil []byte which should be nil")
                }
                // Read non-nil
                if err = nonNullStmt.QueryRow().Scan(&b); err != nil {
                        dbt.Fatal(err)
                }
                if b == nil {
                        dbt.Error("nil []byte which should be non-nil")
                }
                // Insert nil
                b = nil
                success := false
                if err = dbt.db.QueryRow("SELECT ? IS NULL", b).Scan(&success); err != nil {
                        dbt.Fatal(err)
                }
                if !success {
                        dbt.Error("inserting []byte(nil) as NULL failed")
                }
                // Check input==output with input==nil
                b = nil
                if err = dbt.db.QueryRow("SELECT ?", b).Scan(&b); err != nil {
                        dbt.Fatal(err)
                }
                if b != nil {
                        dbt.Error("non-nil echo from nil input")
                }
                // Check input==output with input!=nil
                b = []byte("")
                if err = dbt.db.QueryRow("SELECT ?", b).Scan(&b); err != nil {
                        dbt.Fatal(err)
                }
                if b == nil {
                        dbt.Error("nil echo from non-nil input")
                }

                // Insert NULL
                dbt.mustExec("CREATE TABLE test (dummmy1 int, value int, dummy2 int)")

                dbt.mustExec("INSERT INTO test VALUES (?, ?, ?)", 1, nil, 2)

                var out interface{}
                rows := dbt.mustQuery("SELECT * FROM test")
                defer rows.Close()
                if rows.Next() {
                        rows.Scan(&out)
                        if out != nil {
                                dbt.Errorf("%v != nil", out)
                        }
                } else {
                        dbt.Error("no data")
                }
        })
}

最后补充一下:如果返回的string字段为NULL,就会进入if !str.Valid { }块里面,这时候str.String的值是"",如果你需要换成其他的缺省值就在这里修改它;如果返回的int字段为NULL,同样地,它的值是0,如果你需要换成其他的缺省值也在这里修改它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值