使用gorp在我的
postgresql数据库中更新一行时,我可以成功地使用db.Exec运行更新,所有列都使用正确的信息进行更新,而gorp im只能更新非sql.Null *字段,而休息保持不变.
var db *sql.DB var dbmap *gorp.DbMap func getDB() (*sql.DB,*gorp.DbMap) { if db == nil { var err error db,err = sql.Open("postgres","postgres://xxxxxxxx") db.SetMaxOpenConns(5) db.SetMaxIdleConns(0) dbmap = &gorp.DbMap{Db: db,Dialect: gorp.PostgresDialect{}} dbmap.AddTableWithName(WirelessNetwork{},"network").SetKeys(true,"Id") if err != nil { log.Panic(err) } } return db,dbmap } type WirelessNetwork struct { Id int `db:"id"` Ssid string `db:"ssid"` Lat sql.NullFloat64 `db:"lat"` Lon sql.NullFloat64 `db:"lon"` Sec sql.NullString `db:"sec"` Bssid sql.NullString `db:"bssid"` Channel sql.NullInt64 `db:"channel"` Found bool `db:"found"` Datefirst sql.NullString `db:"datefirst"` Datelast sql.NullString `db:"datelast"` } npr := new(WirelessNetwork) npr.Id = getNetworkId(ssid) npr.Ssid = ssid npr.Lat = dbProbes[index].Lat npr.Lon = dbProbes[index].Lon npr.Sec = dbProbes[index].Sec npr.Bssid = dbProbes[index].Bssid npr.Channel = dbProbes[index].Channel npr.Found = dbProbes[index].Found npr.Datefirst = dbProbes[index].Datefirst npr.Datelast = dbProbes[index].Datelast npr.Found = true
这个工作
db,_ := getDB() db.Exec("UPDATE network SET ssid=$1,lat=$2,lon=$3,sec=$4,channel=$5,found=$6,datefirst=$7,datelast=$8,bssid=$9 WHERE id=$10",npr.Ssid,npr.Lat.Float64,npr.Lon.Float64,npr.Sec.String,npr.Channel.Int64,npr.Found,npr.Datefirst.String,npr.Datelast.String,npr.Bssid.String,getNetworkId(ssid))
这不行
func updateNetwork(n *WirelessNetwork) { _,dbmap := getDB() _,err := dbmap.Update(n) if err != nil { log.Fatal("updateNetwork - ",err) } }
解决方法
sql.Null *类型是具有有效布尔字段的结构,它指示该值是否为NULL. boolean的初始值为false,因此除非您明确验证数据,否则将向数据库发送NULL.你没有告诉我们,什么是dbProbes,它是如何获取数据的,但是如果它是初始化的
dbProbes[index].Lat = sql.NullFloat64{Float64: lat}
那么有效仍然为false,您需要手动验证数据:
dbProbes[index].Lat = sql.NullFloat64{Float64: lat,Valid: true}
或使用扫描方法:
err = dbProbes[index].Lat.Scan(lat)