You can use aliases for types provided by sql package such as (NullInt64, NullString etc...). There are two advantages of using that, one you can scan null values and can get in golang structure and second you can marshal that struct in JSON.

Please, look at the sample code:

// NullInt64 is an alias for sql.NullInt64 data type
type NullInt64 sql.NullInt64

// Scan implements the Scanner interface for NullInt64
func (ni *NullInt64) Scan(value interface{}) error {
    var i sql.NullInt64
    if err := i.Scan(value); err != nil {
        return err
    }
    // if nil the make Valid false
    if reflect.TypeOf(value) == nil {
        *ni = NullInt64{i.Int64, false}
    } else {
        *ni = NullInt64{i.Int64, true}
    }
    return nil
}

// MarshalJSON for NullInt64
func (ni *NullInt64) MarshalJSON() ([]byte, error) {
    if !ni.Valid {
        return []byte("null"), nil
    }
    return json.Marshal(ni.Int64)
}

Please, have a look at this article, it would be very helpful about handling null values in golang and how to use it in JSON.

Answer from rsudip90 on Stack Overflow
🌐
Medium
medium.com › @dual › ways-to-handle-sql-null-values-in-go-e237f31b82fc
Ways to handle SQL NULL values in Go | Medium
July 14, 2025 - COALESCE is an SQL function found in most relational database systems such as SQLite, PostgreSQL, MySQL, SQL Server, and Oracle. This function attempts to return the first non-NULL value based on its given arguments. Check for documentation. type User struct { Id int64 Name string Age int32 } err := db.QueryRow("SELECT COALESCE(NULL, '')").Scan(&u.Name)
🌐
Ente
ente.io › home › blog › go nulls and sql
Go nulls and SQL
May 22, 2022 - This is something which comes up when we try to interact with, for example, SQL or JSON. In SQL, a string may both be empty ("", just like a zeroable in Go) and NULL (like a Go nil). But a Go string can only be zeroable, not nil.
🌐
Google Groups
groups.google.com › g › golang-dev › c › O1SiEOfMMGo
scanning an sql NULL into an int or string
Scan could return sql.ErrNull, but you wouldn't necessarily know which column was null. Seems a bit useless. It could return a custom error type with a column index or name, but that seems like a pain to check for. ... Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message ... >> BTW, I haven't looked at your code (sorry), but one way to implement >> NULL would be >> >> var name *string >> var arg *int >> err := rows.Scan(&name, &arg) >> >> in which NULL sets the pointers to nil and values set them to point to >> values.
🌐
Go-database-sql
go-database-sql.org › nulls.html
Working with NULLs
There are types for nullable booleans, strings, integers, and floats.
🌐
Pliutau
pliutau.com › working-with-db-nulls
Working with DB nulls in Golang
The sql.Null[String,Int64,Float64,Bool] types have two fields: a typed value and a boolean Valid. You can use the typed value to get either the value that’s been set, or the type’s “zero value” if it hasn’t been set.
🌐
Heystephenwood
heystephenwood.com › 2018 › 06 › working-with-nulls-with-sql-databases.html
Hey Stephen Wood: Working with nulls with sql databases in Golang
package main import ( "database/sql" "encoding/json" "log" "net/http" "strconv" _ "github.com/mattn/go-sqlite3" "gopkg.in/guregu/null.v3" ) // DB is the database connector var DB *sql.DB // Person represents a single row in a database. Using the type null. type Person struct { Name string `json:"id"` Age int `json:"age"` NickName null.String `json:"nickname"` // Optional } // InsertPerson adds a person to the database func InsertPerson(p Person) { cnx, _ := DB.Prepare(` INSERT INTO people (name, age, nickname) VALUES (?, ?, ?)`) defer cnx.Close() log.Printf("Adding person: %v\n", p) cnx.Exec(p
🌐
GitHub
github.com › guregu › null › blob › main › int.go
null/int.go at main · guregu/null
return Int{ NullInt64: sql.NullInt64{ Int64: i, Valid: valid, }, } } · // IntFrom creates a new Int that will always be valid. func IntFrom(i int64) Int { return NewInt(i, true) } · // IntFromPtr creates a new Int that be null if i is nil. func IntFromPtr(i *int64) Int { if i == nil { return NewInt(0, false) } return NewInt(*i, true) } ·
Author   guregu
Find elsewhere
🌐
Reddit
reddit.com › r/golang › what is your approach to handling possible nulls in sql
r/golang on Reddit: What is your approach to handling possible NULLs in SQL
October 11, 2022 -

It's quite a common situation when you need to do work with a column that can be null in SQL (PostgreSQL in my case). I wish I could add NOT NULL constraints to every single column but that doesn't always make sense from the domain perspective.

The standard workarounds are to the best of my knowledge: using a pointer (say, *string or *int) to make sure that a potentially NULL value can be safely scanned into this field OR using a nullable SQL type like sql.NullString.

Russ Cox himself, if my memory serves me well, once wrote that effectively those two options can be considered the same. That said, the letter gets marshaled in a peculiar way (with all that Valid stuff), which is fixable but unpleasant to have.

Until recently, my choice was using pointers. The only drawback is the necessity to handle/check for NULLs in code, which is, to be more accurate, related to anything with pointers.

What I thought today is that it probably makes sense to use COALESCE in SQL to guarantee that NULLs can not be returned in the first place thus making zero values somehow useful :)

This solves the scanning issue and using the omitempty tag ensures the JSON output looks good.

One possible caveat I can think of is that there is now no way to tell whether a field is NULL or just an empty string/0 in the table. For strings, I can easily believe that this difference doesn't make a lot of sense. After all, having an empty string is always suspicious. It's different, though, with integers where 0 can be quite a valid value.

What do you think about this COALESCE approach and what is your favorite one to handle NULLs from SQL?

🌐
Medium
medium.com › aubergine-solutions › how-i-handled-null-possible-values-from-database-rows-in-golang-521fb0ee267
The way I handled possible null values from database rows in Golang! | by Sudip | Aubergine Solutions | Medium
November 10, 2019 - use test;CREATE TABLE Article( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL, `pubdate` datetime DEFAULT NULL, `body` text, `userid` int DEFAULT NULL, PRIMARY KEY(`id`) );SELECT * FROM Article; (Empty Set)
Top answer
1 of 1
5

You shouldn't be checking like that at all. The nullable types are intended for use directly in structs:

type Profile struct {
    ID        sql.NullInt64  `json:"id"`
    CreatedAt time.Time      `json:"created_at"`
    UpdatedAt time.Time      `json:"updated_at"`
    FirstName sql.NullString `json:"first_name"`
    LastName  sql.NullString `json:"last_name"`
    Age       sql.NullInt64  `json:"age"`
}

Then access the values using, for example, product.FirstName.String(). There is no reason for checking product.FirstName.Valid except where you actually care about the distinction between nil and an empty value (in the examples in your question, you clearly don't care about this distinction).

An alternative, which may be more suitable in some situations, is to just use a pointer:

type Profile struct {
    ID        *int      `json:"id"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
    FirstName *string   `json:"first_name"`
    LastName  *string   `json:"last_name"`
    Age       *int      `json:"age"`
}

Of course then any code that uses these variables must dereference them, and check for nil, so this may not always be the most desirable, depending on how you use the values.

A third option, if you never care about the distinction between a NULL value and and empty value, is to create your own type which treats these the same. Example:

type myString string

func (s *myString) Scan(src interface{}) error {
    if src == nil {
        return nil
    }
    if value, ok := src.(string); ok {
        *s = value
        return nil
    }
    return fmt.Errorf("Unsupported type for myString: %T", src)
}
🌐
Go Packages
pkg.go.dev › gopkg.in › guregu › null.v3
null package - gopkg.in/guregu/null.v3 - Go Packages
Marshals to JSON null if SQL source data is null. Zero (blank) input will not produce a null String. Can unmarshal from sql.NullString JSON input or string input. Nullable int64.
🌐
Reddit
reddit.com › r/golang › use sql.nullsring or *string to handle database null values in go?
r/golang on Reddit: Use sql.NullSring or *string to handle database NULL values in Go?
June 21, 2016 -

There are two ways how to work with database NULL values in Go:

  1. sql.NullString, sql.NullBool, sql.NullInt64

  2. *string, *bool, *int64

I have found two different opinions on this topic.

Opinion A, Russ Cox.

Any reason to use sql.NullString rather than *string? - https://groups.google.com/forum/#!topic/golang-nuts/vOTFu2SMNeA

There's no effective difference. We thought people might want to use NullString because it is so common and perhaps expresses the intent more clearly than *string. But either will work.

Opinion B, Arne Hormann.

Consider pointers to string (Int, etc) rather than NullString (Int, etc) - https://github.com/VividCortex/go-database-sql-tutorial/issues/32

*string is stored in an interface, so you have 3 levels of indirection (interface -> pointer to string -> pointer to bytes). NullString only has 2 levels of indirection and takes up less space in memory, which is why it's used in database/sql.

It would be useful for people to find all possible arguments regarding this topic in single place.

Please put your opinons and/or references.

🌐
Aubergine Solutions
aubergine.co › insights › how-i-handled-possible-null-values-from-database-rows-in-golang
[Guide] Handling Null Values from Database Rows in Golang
If it’s True then it does json marshal over int64 data else return bytes of string “null” (which is one of the primitive values in JavaScript). You’ll see a similar style of code in the gist. ... As Alexandre Bodin suggested in comments that we can extend sql.Nullxxxtype into our struct so that we can totally avoid the hassle of re-implement Scan method.
🌐
GitHub
github.com › golang › go › issues › 57099
proposal: database/sql: add configuration option to ignore null values in Scan · Issue #57099 · golang/go
October 14, 2022 - Currently, when scanning a NULL database value into a go type that is not nil-able, this package throws an error like "sql: Scan error on column index 0, name "foo": converting NULL to int is unsupported". This makes logical sense; nil and 0 are different values, and only the latter can be assigned to an int.
Published   Dec 06, 2022
🌐
GitHub
github.com › golang › go › issues › 47953
proposal: databse/sql: add NullUint64 · Issue #47953 · golang/go
April 10, 2021 - Hey! I maintain an entity framework for Go named ent, and we're having troubles handling nullable uint64 types as the official sql package doesn't support it. Using NullInt64 is not enough as some databases accept values that are greater...
Published   Aug 25, 2021