我正在编写一个基本程序来从数据库表中读取值并在表中打印。该表由一个古老的程序填充。该行中的某些字段是可选的,当我尝试将它们作为字符串读取时,出现以下错误:panic: sql: Scan error on column index 2: unsupported driver -> Scan pair: <nil> -> *string在我阅读了类似问题的其他问题后,我想出了以下代码来处理 nil 值。该方法在实践中效果很好。我得到纯文本和空字符串的值而不是 nil 值。但是,我有两个顾虑:这看起来效率不高。我需要像这样处理 25 个以上的字段,这意味着我将每个字段作为字节读取并转换为字符串。太多的函数调用和转换。两个结构体来处理数据等等...代码看起来很丑。它已经看起来很复杂,有 2 个字段,并且在我 25+ 时变得不可读我做错了吗?有没有更好/更干净/更高效/惯用的 golang 方式来从数据库中读取值?我发现很难相信像 Go 这样的现代语言不会优雅地处理数据库返回。提前致谢!代码片段:// DB read formattype udInfoBytes struct { id []byte state []byte}// output formattype 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}
3 回答
翻过高山走不出你
TA贡献1875条经验 获得超3个赞
有不同的类型来处理null值从数据库中,如来sql.NullBool,sql.NullFloat64等等。
例如:
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
}
慕的地8271018
TA贡献1796条经验 获得超4个赞
另一种解决方案是使用 COALESCE 函数在 SQL 语句本身中处理此问题(尽管并非所有 DB 都可能支持此功能)。
例如,您可以改为使用:
q := fmt.Sprintf("SELECT id,COALESCE(state, '') as state FROM Mytable WHERE id='%s' ", ud)
如果它在数据库中存储为 NULL,这将有效地为 'state' 提供一个空字符串的默认值。
- 3 回答
- 0 关注
- 176 浏览
添加回答
举报
0/150
提交
取消