使用Go标准库database/sql,Rows.Scan如果遇到NULL,则会报错,并且停止Scan后续的字段,导致获得的数据不完整。
比如:
```
type TblUser struct {
Id int64
LastIp string
NickName string
Avatar string
Lang string
}
```
假设LastIp为NULL,其他字段都有数据,但是Rows.Scan的时候,只能识别出Id,其他字段都无法正确读出。
而NULL在数据库又很容易遇到,摸索了一段时间,找到一个方案,先上代码:
```
m := new(TblUser)
dest := []interface{}{&(m.Id), &(m.LastIp), &(m.NickName), &(m.Avatar)}
newDest := make([]interface{}, 0, len(dest))
empty := sql.NullBool{}
queryValue := reflect.Indirect(reflect.ValueOf(query))
queryValue = queryValue.FieldByName("lastcols")
cnt := queryValue.Len()
for i := 0; i < cnt; i++ {
v := queryValue.Index(i)
v_ok := false
if v.IsValid() {
if v.InterfaceData()[0] != 0 {
newDest = append(newDest, dest[i])
v_ok = true
}
}
if v_ok == false {
newDest = append(newDest, &empty)
}
}
_ = query.Scan(newDest...)
```
思路是:
1. 通过反射,拿得从数据库获得的数据,即:lastcols
lastcols是在结构体的非公开变量,所以需要反射
2. 遍历lastcols,获取每项的interfaceData(),判断是否有数据
3. 如果没有数据,则将scan结果放到一个sql.NullBool{}变量,该类型由引擎提供,可以接受NULL
4. 最后就可以正常scan了
有疑问加站长微信联系(非本文作者))