sql:列索引19上的扫描错误,名称“ L2Name”:不支持的扫描,存储驱动程序。将值类型<nil>转换为类型* string

时间:2019-02-11 22:16:02

标签: mysql sql go

我正在尝试使用Golang和内置的database / sql库以及postgres lib / pq库,以尝试从某些记录中具有空值的数据库中读取数据。代码可以编译,但是当我尝试运行它时,出现以下错误: sql: Scan error on column index 19, name "L2Name": unsupported Scan, storing driver.Value type <nil> into type *string

我有这样的结构:

// Assets Info Dataset
type AssetInfo struct {
  Asset_id string
  Asset_name string
  Organisation_id string
  LastCheckIn string
  Asset_Status string
  Asset_latitude string
  Asset_longitude string
  Organisation_name string
  CurrentDevice_name string
  AssetActiveDeviceType string
  AssetSafetyTimer float32
  TemplateName string
  TemplateL2name string
  TemplateL2contact string
  TemplateL3name string
  TemplateL3contact string
  TemplateL4name string
  TemplateL4contact string
  TemplateEscalationNotes string
}

这是我的代码:

db, err := sql.Open("mysql", "stevejc:19939c@tcp(127.0.0.1:3306)/johntcw_loneworker?charset=utf8")
  checkErr(err)
  defer db.Close()

  for {
    sqlstatement := "SELECT" +
    " assets.ID, assets.Name, assets.LastCheckIn, assets.Status, assets.OffTimer," +
    " assets.SafetyTimer, assets.HazardTimer, assets.HazardTimerStartedTime, assets.LastSignedOn," +
    " assets.Latitude, assets.Longitude, assets.TemplateID, assets.ActiveDeviceType, assets.CurrentDeviceID," +
    " assets.OffTimerTemp, assets.OrganisationID," +
    " organisations.Name As OrganisationName," +
    " devices.Label As CurrentDeviceName," +
    " templates.Name As TemplateName, templates.L2Name, templates.L2Contact, templates.L3Name, templates.L3Contact," +
    " templates.L4Name, templates.L4Contact, templates.Note" +
    " FROM assets" +
    " LEFT JOIN organisations ON assets.OrganisationID = organisations.ID" +
    " LEFT JOIN devices ON assets.CurrentDeviceID = devices.ID" +
    " JOIN templates ON assets.TemplateID = templates.ID" +
    " WHERE assets.Status != 'Not monitoring' AND assets.AssetStatus = 'Active' AND assets.Display != '0'"
    // select monitoring assets
    rows, err := db.Query(sqlstatement)
    checkErr(err)

    for rows.Next() {
      var assetid string
      var name string
      var lastcheckin string
      var status string
      var offtimer float32
      var offtimertemp float32
      var safetytimer float32
      var hazardtimer float32
      var hazardstarttime string
      var lastsignedon string
      var lat string
      var lon string
      var templateid string
      var activedevicetype string
      var currentdeviceid string
      var organisationid string
      var organisationname string
      var currentdevicename string
      var templatename string
      var l2name string
      var l2contact string
      var l3name string
      var l3contact string
      var l4name string
      var l4contact string
      var escalationnotes string


      err = rows.Scan(&assetid,
        &name,
        &lastcheckin,
        &status,
        &offtimer,
        &safetytimer,
        &hazardtimer,
        &hazardstarttime,
        &lastsignedon,
        &lat,
        &lon,
        &templateid,
        &activedevicetype,
        &currentdeviceid,
        &offtimertemp,
        &organisationid,
        &organisationname,
        &currentdevicename,
        &templatename,
        &l2name,
        &l2contact,
        &l3name,
        &l3contact,
        &l4name,
        &l4contact,
        &escalationnotes)
      checkErr(err)

      assetinfo := new(AssetInfo)
      assetinfo.Asset_id = assetid
      assetinfo.Asset_name = name
      assetinfo.LastCheckIn = lastcheckin
      assetinfo.Asset_Status = status
      assetinfo.Organisation_id = organisationid
      assetinfo.Asset_longitude = lon
      assetinfo.Asset_latitude = lat
      assetinfo.Organisation_name = organisationname
      assetinfo.CurrentDevice_name = currentdevicename
      assetinfo.AssetActiveDeviceType = activedevicetype
      assetinfo.AssetSafetyTimer = safetytimer
      assetinfo.TemplateName = templatename
      assetinfo.TemplateL2name = l2name
      assetinfo.TemplateL2contact = l2contact
      assetinfo.TemplateL3name = l3name
      assetinfo.TemplateL3contact = l3contact
      assetinfo.TemplateL4name = l4name
      assetinfo.TemplateL4contact = l4contact
      assetinfo.TemplateEscalationNotes = escalationnotes

代码的输出正常,我可以从数据库中获取所有想要的数据。除了SQL错误外,控制台上还印有SQL错误。而且L2Name在这里不是空值,我可以在控制台上打印该值。所以不知道为什么错误显示一个类型?

2 个答案:

答案 0 :(得分:0)

对于可以为NULL的字段,应使用sql.NullString数据结构。 这是更多详细信息:

https://golang.org/pkg/database/sql/#NullString

答案 1 :(得分:0)

最简单的解决方法是使用COALESCE(templates.L2Name,'')将可为空的cols包装在您的sql语句中,感谢@pmk的帮助。

  sqlstatement := "SELECT" +
    " assets.ID, assets.Name, assets.LastCheckIn, assets.Status, assets.OffTimer," +
    " assets.SafetyTimer, assets.HazardTimer, assets.HazardTimerStartedTime, assets.LastSignedOn," +
    " assets.Latitude, assets.Longitude, assets.TemplateID, assets.ActiveDeviceType, assets.CurrentDeviceID," +
    " assets.OffTimerTemp, assets.OrganisationID," +
    " organisations.Name As OrganisationName," +
    " devices.Label As CurrentDeviceName," +
    " templates.Name As TemplateName, COALESCE(templates.L2Name, ''), COALESCE(templates.L2Contact, '')," +
    " COALESCE(templates.L3Name, ''), COALESCE(templates.L3Contact, '')," +
    " COALESCE(templates.L4Name, ''), COALESCE(templates.L4Contact, ''), templates.Note" +
    " FROM assets" +
    " LEFT JOIN organisations ON assets.OrganisationID = organisations.ID" +
    " LEFT JOIN devices ON assets.CurrentDeviceID = devices.ID" +
    " JOIN templates ON assets.TemplateID = templates.ID" +
    " WHERE assets.Status != 'Not monitoring' AND assets.AssetStatus = 'Active' AND assets.Display != '0'"