go - 绕过 Go 中的 sql 空值问题

标签 go

我想使用 Go 为广泛使用空值的现有数据库创建 API。 Go 不会将 null 扫描为空字符串(或等效字符串),因此我需要实现一个解决方法。

我发现的解决方法让我不满意。事实上,由于这个问题,我一直在寻找一种动态语言,但 Go 有一定的吸引力,如果可能的话,我想坚持使用它。以下是不满意的解决方法:

  1. 不要在数据库中使用空值。不合适,因为数据库是预先存在的,我无权干涉它的结构。数据库比我的应用程序更重要,而不是相反。
  2. 在 sql 查询中,在数据到达我的应用程序之前,使用 COALESCE、ISNULL 等将 null 转换为空字符串(或等值字符串)。不适合,因为字段多,表多。除了几个明显的字段(主键、姓氏)之外,我不确定可以依赖哪些字段不会给我一个空值,所以我会防御性地将我的 sql 查询弄得乱七八糟。
  3. 使用sql.NullString , sql.NullInt64, sql.NullFloat64 等将空值转换为空字符串(或等价物)作为将它们设置为目标类型之前的中间步骤。这遇到了与上述相同的问题,只是我弄乱了我的 Go 代码而不是我的 sql 查询。
  4. 使用 *pointers 和 []byte 的组合,将每个项目扫描到内存位置而不将其提交到特定类型([]byte 除外),然后以某种方式处理原始数据。但是要对数据做一些有意义的事情,你必须将它转换成更有用的东西,然后你回到 sql.Nullstring 或 if x==nil{handle it},这又是根据具体情况发生的我需要处理的任何领域。因此,再一次,我们看到的是困惑、凌乱、容易出错的代码,我一直在重复自己,而不是在我的编码中保持干练。
  5. 向 Go ORM 库寻求帮助。好吧,我做到了,但令我惊讶的是,他们都没有解决这个问题。
  6. 制作我自己的帮助程序包,将所有空字符串转换为“”,将空整数转换为 0,将空 float 转换为 0.00,将空 bool 值转换为 false 等,并使其成为从 sql 中扫描的过程的一部分驱动程序,生成常规的普通字符串、整数、 float 和 bool 值。

    不幸的是,如果 6 是解决方案,我没有专业知识。我怀疑解决方案会涉及类似“如果要扫描的项目的预期类型是字符串,则将其设为 sql.NullString 并从中提取空字符串。但是如果要扫描的项目是 int,使它成为一个 NullInt64 并从中得到一个零。但是如果 ...(etc)"

有什么我遗漏的吗?谢谢。

最佳答案

使用 sql 扫描目标变量的指针使数据能够被扫描、处理(检查是否 != nil)并编码为 json,从 API 发送出去, 必须到处放置数百个 sql.Nullstring、sql.Nullfloat64 等。空值奇迹般地保存下来并通过编码的 json 发送出去。 (见底部的父名)。在另一端,客户端可以使用 javascript 中的 null,后者可以更好地处理它们。

func queryToJson(db *sql.DB) []byte {
    rows, err := db.Query(
      "select mothername, fathername, surname from fams" +
      "where surname = ?", "Nullfather"
    )
    defer rows.Close()

    type record struct {
        Mname, Fname, Surname *string  // the key: use pointers
    }
    records := []record{}

    for rows.Next() {
        var r record
        err := rows.Scan(r.Mname, r.Fname, r.Surname) // no need for "&"
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(r)
        records = append(records, r)
    }
    j, err := json.Marshal(records)
    if err != nil {
        log.Fatal(err)
    }
    return j
}
j := queryToJson(db)
fmt.Println(string(j)) // [{"Mothername":"Mary", "Fathername":null, "Surname":"Nullfather"}]

关于go - 绕过 Go 中的 sql 空值问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32294476/

相关文章:

mysql - 如何避免 GORM 中的竞争条件

firebase - 如何验证 Google Firebase admin SDK 凭据是否正确

json - 您如何编码 sql.NullString 以便输出被展平以仅给出 go 中的值?

google-app-engine - GAE : How to upload files to be accessed by the application?

json - 通过模板将通用JSON转换为XML

go - 如何将 Go 客户端应用程序连接到 IBM VS Code Fabric Extension?

go - 防止 ^C 在 Go 中显示在 Ctrl+C 上

go - Gmail API : Trashing first email seems to remove entire thread

go - 如何从 io.ReadCloser 转到 io.ReadSeeker?

json - 将变量注入(inject) JSON 配置文件