【问题标题】:gorp Update not updatinggorp 更新未更新
【发布时间】:2015-06-13 18:32:41
【问题描述】:

我在使用 gorp 更新我的 postgresql 数据库中的一行时遇到问题,我可以使用 db.Exec 成功运行更新,所有列都使用正确的信息进行更新,而使用 gorp 我只能更新非 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 go gorp


【解决方案1】:

sql.Null* 类型是带有 Valid 布尔字段的结构,它告诉值是否为 NULL。 boolean 的初始值为 false,因此除非您明确验证数据,否则您将向数据库发送 NULL。你没有告诉我们,dbProbes 是什么以及它是如何获取数据的,但是如果它是用类似的东西初始化的

dbProbes[index].Lat = sql.NullFloat64{Float64: lat}

那么Valid 仍然是假的,您需要手动验证您的数据:

dbProbes[index].Lat = sql.NullFloat64{Float64: lat, Valid: true}

或使用Scan 方法:

err = dbProbes[index].Lat.Scan(lat)

【讨论】:

  • 感谢您的回答,这确实对我有用,但它有点难看,有没有更简化的方法来做到这一点?在我发布这个问题之前,我有npr := dbProbes[index],其中dbProbesWirelessNetwork 的一部分,但这也不起作用。现在使用您的解决方案,我必须设置该结构的每个属性?
  • @norwat 这仍然取决于dbProbes 来自哪里。我不能在不知道的情况下推荐任何东西,但是如果您可以在那里验证您的数据,npr := dbProbes[index] 将再次起作用。
  • 抱歉忘了提,dbProbes 来自另一个表,该表也存储WirelessNetwork 对象,然后我尝试根据用户输入将一个表的元素与另一个表匹配。所以本质上dbProbes对应一个包含所有有效字段的sql对象,npr是一个只有2个有效字段的新对象
  • 另一张表中的数据都是NULL吗?如果不是,我会说问题出在您从另一个表中获取数据的方式上。我也不太明白你的最后一句话。 npr 应该是除了两个字段之外的所有 NULL 吗?
  • 不,dbProbes 来自一个所有字段都不为空的表,是的npr 只有两个非空字段
猜你喜欢
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
相关资源
最近更新 更多