---
title: SQLInterface
---

## Introduction

The `database/sql` package provides a generic interface around SQL (or SQL-like) databases. See the [official documentation](https://pkg.go.dev/database/sql/) for details.

This page provides example usage patterns.

## Database driver

The `database/sql` package must be used in conjunction with a database driver.
See https://go.dev/s/sqldrivers for a list of drivers.

The documentation below assumes a driver has been imported.

## Connecting to a database

[`Open`](https://pkg.go.dev/database/sql/#Open)
 is used to create a database handle:

```go
db, err := sql.Open(driver, dataSourceName)
```

Where driver specifies a database driver and dataSourceName
specifies database-specific connection information
such as database name and authentication credentials.

Note that `Open` does not directly open a database connection: this is deferred
until a query is made. To verify that a connection can be made
before making a query, use the
[`PingContext`](https://pkg.go.dev/database/sql/#DB.PingContext)
method:

```go
if err := db.PingContext(ctx); err != nil {
  log.Fatal(err)
}
```

After use, the database is closed using [`Close`](https://pkg.go.dev/database/sql/#DB.Close).

## Executing queries

[`ExecContext`](https://pkg.go.dev/database/sql/#DB.ExecContext)
is used for queries where no rows are returned:

```go
result, err := db.ExecContext(ctx,
	"INSERT INTO users (name, age) VALUES ($1, $2)",
	"gopher",
	27,
)
```

Where result contains the last insert ID and number of
rows affected. The availability of these values is dependent on
the database driver.

[`QueryContext`](https://pkg.go.dev/database/sql/#DB.QueryContext)
is used for retrieval:

```go
rows, err := db.QueryContext(ctx, "SELECT name FROM users WHERE age = $1", age)
if err != nil {
	log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
	var name string
	if err := rows.Scan(&name); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
	log.Fatal(err)
}
```

[`QueryRowContext`](https://pkg.go.dev/database/sql/#DB.QueryRowContext)
is used where only a single row is expected:

```go
var age int64
err := db.QueryRowContext(ctx, "SELECT age FROM users WHERE name = $1", name).Scan(&age)
```

Prepared statements can be created with [`PrepareContext`](https://pkg.go.dev/database/sql/#DB.PrepareContext):

```go
age := 27
stmt, err := db.PrepareContext(ctx, "SELECT name FROM users WHERE age = $1")
if err != nil {
	log.Fatal(err)
}
rows, err := stmt.Query(age)
// process rows
```

[`ExecContext`](https://pkg.go.dev/database/sql/#Stmt.ExecContext), [`QueryContext`](https://pkg.go.dev/database/sql/#Stmt.QueryContext) and [`QueryRowContext`](https://pkg.go.dev/database/sql/#Stmt.QueryContext) can be called on statements. After use, a
statement should be closed with [`Close`](https://pkg.go.dev/database/sql/#Stmt.Close).

## Transactions

Transactions are started with [`BeginTx`](https://pkg.go.dev/database/sql/#DB.BeginTx):

```go
tx, err := db.BeginTx(ctx, nil)
if err != nil {
	log.Fatal(err)
}
```

The [`ExecContext`](https://pkg.go.dev/database/sql/#Tx.ExecContext), [`QueryContext`](https://pkg.go.dev/database/sql/#Tx.QueryContext), [`QueryRowContext`](https://pkg.go.dev/database/sql/#Tx.QueryRowContext) and [`PrepareContext`](https://pkg.go.dev/database/sql/#Tx.PrepareContext) methods already covered can be
used in a transaction.

A transaction must end with a call to [`Commit`](https://pkg.go.dev/database/sql/#Tx.Commit) or [`Rollback`](https://pkg.go.dev/database/sql/#Tx.Rollback).

## Dealing with NULL

If a database column is nullable, one of the types supporting null values should be passed to Scan.

For example, if the name column in the names table is nullable:

```go
var name sql.NullString
err := db.QueryRowContext(ctx, "SELECT name FROM names WHERE id = $1", id).Scan(&name)
...
if name.Valid {
	// use name.String
} else {
	// value is NULL
}
```

Only [`NullByte`](https://pkg.go.dev/database/sql/#NullByte), [`NullBool`](https://pkg.go.dev/database/sql/#NullBool), [`NullFloat64`](https://pkg.go.dev/database/sql/#NullFloat64), [`NullInt64`](https://pkg.go.dev/database/sql/#NullInt64), [`NullInt32`](https://pkg.go.dev/database/sql/#NullInt32) [`NullInt16`](https://pkg.go.dev/database/sql/#NullInt16), [`NullString`](https://pkg.go.dev/database/sql/#NullString) and [`NullTime`](https://pkg.go.dev/database/sql/#NullTime) are implemented in
`database/sql`. Implementations of database-specific null types are left
to the database driver. User types supporting `NULL` can be created by implementing interfaces [`database/sql/driver.Valuer`](https://pkg.go.dev/database/sql/driver/#Valuer) and [`database/sql.Scanner`](https://pkg.go.dev/database/sql/#Scanner).

You can also pass pointer types. Be careful for performance issues as it requires extra memory allocations.

```go
var name *string
err := db.QueryRowContext(ctx, "SELECT name FROM names WHERE id = $1", id).Scan(&name)
```

# Getting a table

If you want an struct array from your SQL query.

```go
func getTable[T any](rows *sql.Rows) (out []T) {
	var table []T
	for rows.Next() {
		var data T
		s := reflect.ValueOf(&data).Elem()
		numCols := s.NumField()
		columns := make([]interface{}, numCols)

		for i := 0; i < numCols; i++ {
			field := s.Field(i)
			columns[i] = field.Addr().Interface()
		}

		if err := rows.Scan(columns...); err != nil {
			fmt.Println("Case Read Error ", err)
		}

		table = append(table, data)
	}
	return table
}
```

Make sure to deal with nulls from the database.

```go
type User struct {
  UUID  sql.NullString
  Name  sql.NullString
}

rows, err := db.Query("SELECT * FROM Users")
cases := getTable[User](rows)
```
