为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中绕过 sql 空值问题

在 Go 中绕过 sql 空值问题

Go
慕尼黑8549860 2021-11-01 17:07:59
我想使用 Go 为广泛使用空值的现有数据库创建 API。Go 不会将 null 扫描为空字符串(或等效项),因此我需要实现一种解决方法。我发现的解决方法让我不满意。事实上,因为这个问题,我去寻找一种动态语言,但 Go 有一些吸引力,如果可能的话,我想坚持下去。以下是不满足的解决方法:不要在数据库中使用空值。不合适,因为数据库是预先存在的,我无权干涉它的结构。数据库比我的应用程序更重要,而不是相反。在 sql 查询中,在数据到达我的应用程序之前,使用 COALESCE、ISNULL 等将空值转换为空字符串(或等效值)。不适合,因为有很多字段和很多表。除了几个明显的(主键、姓氏)之外,我不确定可以依赖哪些字段不给我一个空值,所以我会防御性地将我的 sql 查询到处乱七八糟。使用sql.NullString、 sql.NullInt64 、 sql.NullFloat64 等将空值转换为空字符串(或等效值)作为中间步骤,然后再将它们设置为目标类型。这遇到了与上述相同的问题,只是我把 Go 代码弄得乱七八糟,而不是我的 sql 查询。使用 *pointers 和 []byte 的组合,将每个项目扫描到内存位置,而不将其提交给特定类型(除了 []byte),然后以某种方式处理原始数据。但是要对数据做一些有意义的事情,你必须把它转换成更有用的东西,然后你回到 sql.Nullstring 或者如果 x==nil{handle it},这又是在逐案基础上发生的我需要处理的任何领域。所以,再一次,我们正在查看混乱、凌乱、容易出错的代码,我一直在重复自己,而不是在我的编码中枯燥乏味。向 Go ORM 库寻求帮助。好吧,我做到了,但令我惊讶的是,他们都没有解决这个问题。制作我自己的辅助包,将所有空字符串转换为"",空整数转换为0,空浮点数转换为0.00,空布尔值转换为false等,并使其成为从sql驱动程序扫描进来的过程的一部分,从而导致常规,普通字符串、整数、浮点数和布尔值。不幸的是,如果 6 是解决方案,我没有专业知识。我怀疑该解决方案将涉及诸如“如果要扫描到的项目的预期类型是字符串,则将其设为 sql.NullString 并从中提取一个空字符串。但是如果要扫描到的项目是一个 int,使它成为 NullInt64 并从中得到一个零。但是如果......(等)“有什么我错过了吗?谢谢你。
查看完整描述

1 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

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


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"}]



查看完整回答
反对 回复 2021-11-01
  • 1 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信