如何在Go中从Postgres中获取一个NULL布尔值?

huangapple go评论79阅读模式
英文:

How can I fetch a NULL boolean from Postgres in Go?

问题

Go语言中bool类型的零值是false。Postgres支持未定义的BOOL类型,表示为NULL。这在尝试从Postgres中获取BOOL值时会导致问题:

rows,err := db.Query("SELECT UNNEST('{TRUE,FALSE,NULL}'::BOOL[])");
if err != nil {
    log.Fatal(err)
}
for rows.Next() {
    var value bool
    if err := rows.Scan(&value); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Value: %t\n",value);
}

输出:

Value: true  
Value: false  
2014/11/17 09:34:26 sql: Scan error on column index 0: sql/driver: couldn't convert <nil> (<nil>) into type bool

如何解决这个问题最符合惯用方式?我想到的两个解决方案都不太理想:

  1. 不使用Go的bool类型。相反,我可能会使用字符串,并进行自己的转换,考虑到nil的情况。
  2. 通过使用COALESCE()或其他方法,始终确保Postgres中的BOOL值为TRUE或FALSE。
英文:

Go's zero value for a bool type is false. Postgres supports an undefined BOOL type, represented as NULL. This leads to problems when trying to fetch a BOOL value from Postgres in Go:

rows,err := db.Query(&quot;SELECT UNNEST(&#39;{TRUE,FALSE,NULL}&#39;::BOOL[])&quot;);
if err != nil {
    log.Fatal(err)
}
for rows.Next() {
    var value bool
    if err := rows.Scan(&amp;value); err != nil {
        log.Fatal(err)
    }
    fmt.Printf(&quot;Value: %t\n&quot;,value);
}

Output:

<!-- language: lang-none -->

Value: true  
Value: false  
2014/11/17 09:34:26 sql: Scan error on column index 0: sql/driver: couldn&#39;t convert &lt;nil&gt; (&lt;nil&gt;) into type bool

What's the most idiomatic way around this problem? The two solutions I have imagined are neither very attractive:

  1. Don't use Go's bool type. Instead I would probably use a string, and do my own conversion which accounts for nil
  2. Always make sure BOOLs are either TRUE or FALSE in Postgres by using COALESCE() or some other means.

答案1

得分: 8

请参考标准库中的http://golang.org/pkg/database/sql/#NullBool。

NullBool表示可能为空的布尔值。NullBool实现了Scanner接口,因此可以用作扫描目标,类似于NullString。

英文:

See http://golang.org/pkg/database/sql/#NullBool in the standard library.

> NullBool represents a bool that may be null. NullBool implements the
> Scanner interface so it can be used as a scan destination, similar to
> NullString.

答案2

得分: 4

我喜欢使用指针:

for rows.Next() {
    var value *bool

    if err := rows.Scan(&value); err != nil {
        log.Fatal(err)
    }

    if value == nil {
        // 处理空值
    }

    fmt.Printf("Value: %t\n", *value);
}
英文:

My preference is using a pointer:

for rows.Next() {
    var value *bool

    if err := rows.Scan(&amp;value); err != nil {
        log.Fatal(err)
    }

    if value == nil {
        // Handle nil
    }

    fmt.Printf(&quot;Value: %t\n&quot;, *value);
}

答案3

得分: 0

在使用SQL + GraphQL(gqlgen)时,我更喜欢使用指针。

为什么呢?

因为当我生成一个模式时,它会在输出上有指针,这样就更容易与包含指针的相关结构连接起来(这些结构处理数据库操作)。

英文:

In case of using SQL + graphQL (gqlgen) my preference is using pointers as well.

Why?

Because when I generate a schema it will have pointers on the output and this is much easy to connect with a relevant struct which contains pointers (which handle DB operations).

huangapple
  • 本文由 发表于 2014年11月17日 23:38:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/26976251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定