首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理数据库中的零返回值?

如何处理数据库中的零返回值?
EN

Stack Overflow用户
提问于 2015-02-21 06:20:56
回答 5查看 15K关注 0票数 12

我正在编写一个基本程序,从数据库表中读取值并在表中打印。这张桌子上有一个古老的程序。行中的某些字段是可选的,当我试图将它们作为字符串读取时,会得到以下错误:

代码语言:javascript
运行
复制
panic: sql: Scan error on column index 2: unsupported driver -> Scan pair: <nil> -> *string

在阅读了其他类似问题的问题后,我想出了下面的代码来处理零值。该方法在实际应用中效果良好。我以纯文本和空字符串来获取值,而不是零值。

不过,我有两项关注:

  1. 这看上去没有效率。我需要像这样处理25+字段,这意味着我以字节的形式读取每个字段并转换为string。函数调用和转换太多。两个处理数据的结构等等..。
  2. 代码看起来很难看。它看上去已经被两个字段弄得错综复杂,当我转到25+时,它变得不可读了

我做错了吗?是否有一种更好/更干净/高效/熟能生巧的方法从数据库读取值?

我很难相信像Go这样的现代语言不会优雅地处理数据库。

提前感谢!

代码片段:

代码语言:javascript
运行
复制
// DB read format
type udInfoBytes struct {
  id                     []byte
  state                  []byte
}

// output format
type udInfo struct {
  id                     string
  state                  string
}

func CToGoString(c []byte) string {
  n := -1
  for i, b := range c {
    if b == 0 {
      break
    }
    n = i
  }
  return string(c[:n+1])
}

func dbBytesToString(in udInfoBytes) udInfo {

  var out udInfo
  var s string
  var t int

  out.id = CToGoString(in.id)
  out.state = stateName(in.state)
  return out
}

func GetInfo(ud string) udInfo {

  db := getFileHandle()
  q := fmt.Sprintf("SELECT id,state FROM Mytable WHERE id='%s' ", ud)

  rows, err := db.Query(q)
  if err != nil {
    log.Fatal(err)
  }
  defer rows.Close()
  ret := udInfo{}
  r := udInfoBytes{}
  for rows.Next() {
    err := rows.Scan(&r.id, &r.state)

    if err != nil {
      log.Println(err)
    }
    break
  }
  err = rows.Err()
  if err != nil {
    log.Fatal(err)
  }

  ret = dbBytesToString(r)
  defer db.Close()
  return ret
}

编辑:

我希望有这样的东西,在这里,我不必担心处理NULL,并自动将它们作为空字符串读取。

代码语言:javascript
运行
复制
// output format
type udInfo struct {
  id                     string
  state                  string
}

func GetInfo(ud string) udInfo {

  db := getFileHandle()
  q := fmt.Sprintf("SELECT id,state FROM Mytable WHERE id='%s' ", ud)

  rows, err := db.Query(q)
  if err != nil {
    log.Fatal(err)
  }
  defer rows.Close()
  r := udInfo{}

  for rows.Next() {
    err := rows.Scan(&r.id, &r.state)

    if err != nil {
      log.Println(err)
    }
    break
  }
  err = rows.Err()
  if err != nil {
    log.Fatal(err)
  }

  defer db.Close()
  return r
}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-02-21 08:53:05

有不同的类型来处理来自数据库的null值,如sql.NullBoolsql.NullFloat64等。

例如:

代码语言:javascript
运行
复制
 var s sql.NullString
 err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
 ...
 if s.Valid {
    // use s.String
 } else {
    // NULL value
 }
票数 24
EN

Stack Overflow用户

发布于 2015-02-21 15:11:48

go的数据库/sql包句柄类型指针。

代码语言:javascript
运行
复制
package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
    "log"
)

func main() {
    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    _, err = db.Exec("create table foo(id integer primary key, value text)")
    if err != nil {
        log.Fatal(err)
    }
    _, err = db.Exec("insert into foo(value) values(null)")
    if err != nil {
        log.Fatal(err)
    }
    _, err = db.Exec("insert into foo(value) values('bar')")
    if err != nil {
        log.Fatal(err)
    }
    rows, err := db.Query("select id, value from foo")
    if err != nil {
        log.Fatal(err)
    }
    for rows.Next() {
        var id int
        var value *string
        err = rows.Scan(&id, &value)
        if err != nil {
            log.Fatal(err)
        }
        if value != nil {
            fmt.Println(id, *value)
        } else {
            fmt.Println(id, value)
        }
    }
}

你应该如下所示:

代码语言:javascript
运行
复制
1 <nil>
2 bar
票数 8
EN

Stack Overflow用户

发布于 2017-02-01 17:06:01

另一种解决方案是在SQL语句本身中使用聚结函数来处理这个问题(尽管并非所有DB都可能支持这一点)。

例如,您可以使用:

代码语言:javascript
运行
复制
q := fmt.Sprintf("SELECT id,COALESCE(state, '') as state FROM Mytable WHERE id='%s' ", ud)

在数据库中将空字符串作为空字符串存储为NULL时,它实际上给出了空字符串的默认值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28642838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档