为了账号安全,请及时绑定邮箱和手机立即绑定

编组空 map[string]interface{} 导致“null”而不是 nil

编组空 map[string]interface{} 导致“null”而不是 nil

Go
鸿蒙传说 2021-10-18 10:09:37
如果我尝试执行以下操作,Go 会在我的 PostgreSQL 数据库的 jsonb 列中插入“null”,并且 structs 属性(在这种情况下为 map[string]interface{} 类型)为空,则出现问题:accessMembers, _ := json.Marshal(c.AccessMembers)进行测试打印它输出的值与存储到数据库中的值相同:fmt.Println(string(accessMembers)) // equals the string "null"问题是我需要它是 - nil(不是字符串,而是 Golang nil),所以当我在下面的 Exec 函数中使用它时:sqlStr := `UPDATE my_table SET access_members=$1 WHERE id=$2;`_, err := db.Exec(sqlStr, accessMembers, c.Id)它应该等效于(有效!!):_, err := db.Exec(sqlStr, nil, c.Id)我尝试了很多不同的解决方法,我认为这些方法必须有效,但它们没有。例如。var accessMembers []byteam, _ := json.Marshal(c.AccessMembers)if string(am) != "null"{    accessMembers = am}sqlStr := `UPDATE my_table SET access_members=$1 WHERE id=$2;`_, err := db.Exec(sqlStr, accessMembers, c.Id)这会导致以下错误:“pq:json 类型的输入语法无效”我不明白为什么这与在 Exec 函数参数中显式写入 nil 不同,因为 []byte 显然必须为零,对吗?我在这里做错了什么?这是我希望它会起作用的方式:http : //play.golang.org/p/UoLAGfhhRl回答:var accessMembers interface{} = nilif c.AccessMembers != nil {    j, _ := json.Marshal(c.AccessMembers)    accessMembers = j}感谢 thwd 基本上提供了解决方案,并指出了数据库驱动程序如何以不同的方式编组 nil,建议使用 interface{} 而不是 []byte。感谢DonSeba提醒我在使用资源编组之前检查struct字段是否存在,进行字符串转换和比较,这应该更昂贵。
查看完整描述

2 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

我不明白为什么这与在 Exec 函数参数中显式写入 nil 不同,因为 []byte 显然必须为零,对吗?


nil有一个类型。数据库驱动程序nil对 typemap[string]interface{}或[]bytefor interface{} (这是 的第二个参数的类型)的封送方式不同db.Exec。你应该能够做到:


var i interface{} = nil


j, _ := json.Marshal(c.AccessMembers)


if string(j) != "null" {

     i = j

}


sqlStr := `UPDATE content SET access_members=$1 WHERE id=$2;`


_, err := db.Exec(sqlStr, i, c.Id)


查看完整回答
反对 回复 2021-10-18
  • 2 回答
  • 0 关注
  • 236 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信