Handling NULL values with database/sql and Go

SQL Statement Entering Null Values

CREATE TABLE books (
  isbn    char(14) NOT NULL,
  title   varchar(255),
  author  varchar(255),
  price   decimal(5,2)
);

INSERT INTO books (isbn, title, author, price) VALUES
('978-1503261969', 'Emma', 'Jayne Austen', 9.44),
('978-1514274873', 'Journal of a Soldier', NULL, 5.49),
('978-1503379640', 'The Prince', 'Niccolò Machiavelli', NULL);

Go Code showing how to handle the NULL values

Notice sql.NullString as type in the Book struct rather than simple string

package main

import (
  _ "github.com/lib/pq"
  "database/sql"
  "fmt"
  "log"
)

type Book struct {
  Isbn  string
  Title  sql.NullString
  Author sql.NullString
  Price  sql.NullFloat64
}

func main() {
  db, err := sql.Open("postgres", "postgres://user:pass@localhost/bookstore")
  if err != nil {
    log.Fatal(err)
  }
  defer db.Close()

  rows, err := db.Query("SELECT * FROM books")
  if err != nil {
    log.Fatal(err)
  }
  defer rows.Close()

  bks := make([]*Book, 0)
  for rows.Next() {
    bk := new(Book)
    err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price)
    if err != nil {
      log.Fatal(err)
    }
    bks = append(bks, bk)
  }
  if err = rows.Err(); err != nil {
    log.Fatal(err)
  }

  for _, bk := range bks {
    var price string
    if bk.Price.Valid {
      price = fmt.Sprintf("£%.2f", bk.Price.Float64)
    } else {
      price = "PRICE NOT SET"
    }
    fmt.Printf("%s, %s, %s, %s\n", bk.Isbn, bk.Title.String, bk.Author.String, price)
  }
}