3
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

GoでNULL値含むレコードがDBから取得できないとき

sql.NullString(or NullXXX)を使いましょう

stackoverflowにある似たような質問

背景

sqlパッケージのAPIドキュメントのサンプルを参考に値を取ってくるとします。例えばこのようなコードですね。

    age := 27
    rows, err := db.Query("SELECT id, name, address FROM users WHERE age=?", age)
    if err != nil {
            log.Fatal(err)
    }
    defer rows.Close()
    for rows.Next() {
            var id string
            var name string
            var address string
            if err := rows.Scan(&id, &name, &address); err != nil {
                    // もしレコードのどこかにNULL値があれば、errを吐いて終了する。
                    log.Fatal(err)
            }
            fmt.Printf("%s %s %s\n", id, name, address)
    }
    if err := rows.Err(); err != nil {
            log.Fatal(err)
    }

ここでもしnameがNULL値だった場合、errを吐いてこけます。だからNULL値を許容するカラムにはstringではなくsql.NullStringを使いましょうというだけの話なんですが。。。ここでもしrows.Scan()のエラーチェックを省略すると、見かけ上処理が正しく終わったようになってしまうため、ハマってしまうことがあるかと思います。

    age := 27
    rows, err := db.Query("SELECT id, name, address FROM users WHERE age=?", age)
    if err != nil {
            log.Fatal(err)
    }
    defer rows.Close()
    for rows.Next() {
            var id string
            var name string
            var address string

            // 例えば id:"1", name:NULL, address:"Tokyo"というレコードが合った場合、
            // errorチェックを省くと・・・
            // id=1, name=, address=\n
            // が標準出力される。見かけ上、name, addressが空文字だっただけに見える。(実際はaddressにはデータがあるが、Scan()が中断されて取得できていない)
            /*
            if err := rows.Scan(&id, &name, &address); err != nil {
                    log.Fatal(err)
            */
            rows.Scan(&id, &name, &address)           

            fmt.Printf("id=%s name=%s address=%s\n", id, name, address)
    }
    if err := rows.Err(); err != nil {
            log.Fatal(err)
    }

まとめ

  • sql.NullString(NullXXX)使いましょう
  • エラーチェックサボらないようにしましょう
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?