<!--{
  "Title": "Tutorial: Accessing a relational database",
  "Breadcrumb": true
}-->

This tutorial introduces the basics of accessing a relational database with
Go and the `database/sql` package in its standard library.

You'll get the most out of this tutorial if you have a basic familiarity with
Go and its tooling. If this is your first exposure to Go, please see
[Tutorial: Get started with Go](/doc/tutorial/getting-started)
for a quick introduction.

The [`database/sql`](https://pkg.go.dev/database/sql) package you'll
be using includes types and functions for connecting to databases, executing
transactions, canceling an operation in progress, and more. For more details
on using the package, see
[Accessing databases](/doc/database/index).

In this tutorial, you'll create a database, then write code to access the
database. Your example project will be a repository of data about vintage
jazz records.

In this tutorial, you'll progress through the following sections:

1. Create a folder for your code.
2. Set up a database.
3. Import the database driver.
4. Get a database handle and connect.
5. Query for multiple rows.
6. Query for a single row.
7. Add data.

**Note:** For other tutorials, see [Tutorials](/doc/tutorial/index.html).

## Prerequisites {#prerequisites}

*   **An installation of the [MySQL](https://dev.mysql.com/doc/mysql-installation-excerpt/5.7/en/)
    relational database management system (DBMS).**
*   **An installation of Go.** For installation instructions, see
    [Installing Go](/doc/install).
*   **A tool to edit your code.** Any text editor you have will work fine.
*   **A command terminal.** Go works well using any terminal on Linux and Mac,
    and on PowerShell or cmd in Windows.

## Create a folder for your code {#create_folder}

To begin, create a folder for the code you'll write.

1. Open a command prompt and change to your home directory.

    On Linux or Mac:

    ```
    $ cd
    ```

    On Windows:

    ```
    C:\> cd %HOMEPATH%
    ```

    For the rest of the tutorial we will show a $ as the prompt. The
    commands we use will work on Windows too.

2. From the command prompt, create a directory for your code called
    data-access.

    ```
    $ mkdir data-access
    $ cd data-access
    ```


3. Create a module in which you can manage dependencies you will add during
    this tutorial.

    Run the `go mod init` command, giving it your new code's module path.

    ```
    $ go mod init example/data-access
    go: creating new go.mod: module example/data-access
    ```

    This command creates a go.mod file in which dependencies you add will be
    listed for tracking. For more, be sure to see
    [Managing dependencies](/doc/modules/managing-dependencies).

    **Note:** In actual development, you'd specify a module path that's
    more specific to your own needs. For more, see
    [Managing dependencies](/doc/modules/managing-dependencies#naming_module).

Next, you'll create a database.

## Set up a database {#set_up_database}

In this step, you'll create the database you'll be working with. You'll use
the CLI for the DBMS itself to create the database and table, as well as to
add data.

You'll be creating a database with data about vintage jazz recordings on vinyl.

The code here uses the [MySQL CLI](https://dev.mysql.com/doc/refman/8.0/en/mysql.html),
but most DBMSes have their own CLI with similar features.

1. Open a new command prompt.
2. At the command line, log into your DBMS, as in the following example for
    MySQL.

    ```
    $ mysql -u root -p
    Enter password:

    mysql>
    ```

3. At the `mysql` command prompt, create a database.

    ```
    mysql> create database recordings;
    ```

4. Change to the database you just created so you can add tables.

    ```
    mysql> use recordings;
    Database changed
    ```

5. In your text editor, in the data-access folder, create a file called
    create-tables.sql to hold SQL script for adding tables.
6. Into the file, paste the following SQL code, then save the file.

    ```
    DROP TABLE IF EXISTS album;
    CREATE TABLE album (
      id         INT AUTO_INCREMENT NOT NULL,
      title      VARCHAR(128) NOT NULL,
      artist     VARCHAR(255) NOT NULL,
      price      DECIMAL(5,2) NOT NULL,
      PRIMARY KEY (`id`)
    );

    INSERT INTO album
      (title, artist, price)
    VALUES
      ('Blue Train', 'John Coltrane', 56.99),
      ('Giant Steps', 'John Coltrane', 63.99),
      ('Jeru', 'Gerry Mulligan', 17.99),
      ('Sarah Vaughan', 'Sarah Vaughan', 34.98);
    ```

    In this SQL code, you:

    *   Delete (drop) a table called `album`. Executing this command first makes
        it easier for you to re-run the script later if you want to start over
        with the table.

    *   Create an `album` table with four columns: `title`, `artist`, and `price`.
        Each row's `id` value is created automatically by the DBMS.

    *   Add four rows with values.

7. From the `mysql` command prompt, run the script you just created.

    You'll use the `source` command in the following form:

    ```
    mysql> source /path/to/create-tables.sql
    ```

8. At your DBMS command prompt, use a `SELECT` statement to verify you've
    successfully created the table with data.

    ```
    mysql> select * from album;
    +----+---------------+----------------+-------+
    | id | title         | artist         | price |
    +----+---------------+----------------+-------+
    |  1 | Blue Train    | John Coltrane  | 56.99 |
    |  2 | Giant Steps   | John Coltrane  | 63.99 |
    |  3 | Jeru          | Gerry Mulligan | 17.99 |
    |  4 | Sarah Vaughan | Sarah Vaughan  | 34.98 |
    +----+---------------+----------------+-------+
    4 rows in set (0.00 sec)
    ```

Next, you'll write some Go code to connect so you can query.

## Find and import a database driver {#import_driver}

Now that you've got a database with some data, get your Go code started.

Locate and import a database driver that will translate requests you make
through functions in the `database/sql` package into requests the database
understands.

1. In your browser, visit the [SQLDrivers](/wiki/SQLDrivers)
    wiki page to identify a driver you can use.

    Use the list on the page to identify the driver you'll use. For accessing
    MySQL in this tutorial, you'll use
    [Go-MySQL-Driver](https://github.com/go-sql-driver/mysql/).

2. Note the package name for the driver -- here, `github.com/go-sql-driver/mysql`.

3. Using your text editor, create a file in which to write your Go code and
    save the file as main.go in the data-access directory you created earlier.

4. Into main.go, paste the following code to import the driver package.

    ```
    package main

    import "github.com/go-sql-driver/mysql"
    ```

    In this code, you:

    *   Add your code to a `main` package so you can execute it independently.

    *   Import the MySQL driver `github.com/go-sql-driver/mysql`.

With the driver imported, you'll start writing code to access the database.

## Get a database handle and connect {#get_handle}

Now write some Go code that gives you database access with a database handle.

You'll use a pointer to an `sql.DB` struct, which represents access to a
specific database.

#### Write the code

1. Into main.go, beneath the `import` code you just added, paste the following
    Go code to create a database handle.

    ```
    var db *sql.DB

    func main() {
    	// Capture connection properties.
    	cfg := mysql.NewConfig()
    	cfg.User = os.Getenv("DBUSER")
    	cfg.Passwd = os.Getenv("DBPASS")
    	cfg.Net = "tcp"
    	cfg.Addr = "127.0.0.1:3306"
    	cfg.DBName = "recordings"

    	// Get a database handle.
    	var err error
    	db, err = sql.Open("mysql", cfg.FormatDSN())
    	if err != nil {
    		log.Fatal(err)
    	}

    	pingErr := db.Ping()
    	if pingErr != nil {
    		log.Fatal(pingErr)
    	}
    	fmt.Println("Connected!")
    }
    ```

    In this code, you:

    *   Declare a `db` variable of type [`*sql.DB`](https://pkg.go.dev/database/sql#DB).
        This is your database handle.

        Making `db` a global variable simplifies this example. In
        production, you'd avoid the global variable, such as by passing the
        variable to functions that need it or by wrapping it in a struct.

    *   Use the MySQL driver's [`Config`](https://pkg.go.dev/github.com/go-sql-driver/mysql#Config)
        -- and the type's [`FormatDSN`](https://pkg.go.dev/github.com/go-sql-driver/mysql#Config.FormatDSN)
        -– to collect connection properties and format them into a DSN for a connection string.

        The `Config` struct makes for code that's easier to read than a
        connection string would be.

    *   Call [`sql.Open`](https://pkg.go.dev/database/sql#Open)
        to initialize the `db` variable, passing the return value of
        `FormatDSN`.

    *   Check for an error from `sql.Open`. It could fail if, for
        example, your database connection specifics weren't well-formed.

        To simplify the code, you're calling `log.Fatal` to end
        execution and print the error to the console. In production code, you'll
        want to handle errors in a more graceful way.

    *   Call [`DB.Ping`](https://pkg.go.dev/database/sql#DB.Ping) to
        confirm that connecting to the database works. At run time,
        `sql.Open` might not immediately connect, depending on the
        driver. You're using `Ping` here to confirm that the
        `database/sql` package can connect when it needs to.

    *   Check for an error from `Ping`, in case the connection failed.

    *   Print a message if `Ping` connects successfully.

2. Near the top of the main.go file, just beneath the package declaration,
    import the packages you'll need to support the code you've just written.

    The top of the file should now look like this:

    ```
    package main

    import (
    	"database/sql"
    	"fmt"
    	"log"
    	"os"

    	"github.com/go-sql-driver/mysql"
    )
    ```

3. Save main.go.

#### Run the code

1. Begin tracking the MySQL driver module as a dependency.

    Use the [`go get`](/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them)
    to add the github.com/go-sql-driver/mysql module as a dependency for your
    own module. Use a dot argument to mean "get dependencies for code in the
    current directory."

    ```
    $ go get .
    go: added filippo.io/edwards25519 v1.1.0
    go: added github.com/go-sql-driver/mysql v1.8.1
    ```

    Go downloaded this dependency because you added it to the `import`
    declaration in the previous step. For more about dependency tracking,
    see [Adding a dependency](/doc/modules/managing-dependencies#adding_dependency).

2. From the command prompt, set the `DBUSER` and `DBPASS` environment variables
    for use by the Go program.

    On Linux or Mac:

    ```
    $ export DBUSER=username
    $ export DBPASS=password
    ```

    On Windows:

    ```
    C:\Users\you\data-access> set DBUSER=username
    C:\Users\you\data-access> set DBPASS=password
    ```

3. From the command line in the directory containing main.go, run the code by
    typing `go run` with a dot argument to mean "run the package in the
    current directory."

    ```
    $ go run .
    Connected!
    ```

You can connect! Next, you'll query for some data.

## Query for multiple rows {#multiple_rows}

In this section, you'll use Go to execute an SQL query designed to return
multiple rows.

For SQL statements that might return multiple rows, you use the `Query` method
from the `database/sql` package, then loop through the rows it returns. (You'll
learn how to query for a single row later, in the section
[Query for a single row](#single_row).)
#### Write the code

1. Into main.go, immediately above `func main`, paste the following definition
    of an `Album` struct. You'll use this to hold row data returned from the
    query.

    ```
    type Album struct {
    	ID     int64
    	Title  string
    	Artist string
    	Price  float32
    }
    ```

2. Beneath `func main`, paste the following `albumsByArtist` function to query
    the database.

    ```
    // albumsByArtist queries for albums that have the specified artist name.
    func albumsByArtist(name string) ([]Album, error) {
    	// An albums slice to hold data from returned rows.
    	var albums []Album

    	rows, err := db.Query("SELECT * FROM album WHERE artist = ?", name)
    	if err != nil {
    		return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
    	}
    	defer rows.Close()
    	// Loop through rows, using Scan to assign column data to struct fields.
    	for rows.Next() {
    		var alb Album
    		if err := rows.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {
    			return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
    		}
    		albums = append(albums, alb)
    	}
    	if err := rows.Err(); err != nil {
    		return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
    	}
    	return albums, nil
    }
    ```

    In this code, you:

    *   Declare an `albums` slice of the `Album` type you defined. This will hold
        data from returned rows. Struct field names and types correspond to
        database column names and types.

    *   Use [`DB.Query`](https://pkg.go.dev/database/sql#DB.Query) to
        execute a `SELECT` statement to query for albums with the
        specified artist name.

        `Query`'s first parameter is the SQL statement. After the
        parameter, you can pass zero or more parameters of any type. These provide
        a place for you to specify the values for parameters in your SQL statement.
        By separating the SQL statement from parameter values (rather than
        concatenating them with, say, `fmt.Sprintf`), you enable the
        `database/sql` package to send the values separate from the SQL
        text, removing any SQL injection risk.

    *   Defer closing `rows` so that any resources it holds will be released when
        the function exits.

    *   Loop through the returned rows, using
        [`Rows.Scan`](https://pkg.go.dev/database/sql#Rows.Scan) to
        assign each row’s column values to `Album` struct fields.

        `Scan` takes a list of pointers to Go values, where the column
        values will be written. Here, you pass pointers to fields in the
        `alb` variable, created using the `&` operator.
        `Scan` writes through the pointers to update the struct fields.

    *   Inside the loop, check for an error from scanning column values into the
        struct fields.

    *   Inside the loop, append the new `alb` to the `albums` slice.

    *   After the loop, check for an error from the overall query, using
        `rows.Err`. Note that if the query itself fails, checking for an error
        here is the only way to find out that the results are incomplete.

3. Update your `main` function to call `albumsByArtist`.

    To the end of `func main`, add the following code.

    ```
    albums, err := albumsByArtist("John Coltrane")
    if err != nil {
    	log.Fatal(err)
    }
    fmt.Printf("Albums found: %v\n", albums)
    ```

    In the new code, you now:

    *   Call the `albumsByArtist` function you added, assigning its return value to
        a new `albums` variable.

    *   Print the result.

#### Run the code

From the command line in the directory containing main.go, run the code.

```
$ go run .
Connected!
Albums found: [{1 Blue Train John Coltrane 56.99} {2 Giant Steps John Coltrane 63.99}]
```

Next, you'll query for a single row.

## Query for a single row {#single_row}

In this section, you'll use Go to query for a single row in the database.

For SQL statements you know will return at most a single row, you can use
`QueryRow`, which is simpler than using a `Query` loop.

#### Write the code

1. Beneath `albumsByArtist`, paste the following `albumByID` function.

    ```
    // albumByID queries for the album with the specified ID.
    func albumByID(id int64) (Album, error) {
    	// An album to hold data from the returned row.
    	var alb Album

    	row := db.QueryRow("SELECT * FROM album WHERE id = ?", id)
    	if err := row.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {
    		if err == sql.ErrNoRows {
    			return alb, fmt.Errorf("albumsById %d: no such album", id)
    		}
    		return alb, fmt.Errorf("albumsById %d: %v", id, err)
    	}
    	return alb, nil
    }
    ```

    In this code, you:

    *   Use [`DB.QueryRow`](https://pkg.go.dev/database/sql#DB.QueryRow)
        to execute a `SELECT` statement to query for an album with the
        specified ID.

        It returns an `sql.Row`. To simplify the calling code
        (your code!), `QueryRow` doesn't return an error. Instead,
        it arranges to return any query error (such as `sql.ErrNoRows`)
        from `Rows.Scan` later.

    *   Use [`Row.Scan`](https://pkg.go.dev/database/sql#Row.Scan) to copy
        column values into struct fields.

    *   Check for an error from `Scan`.

        The special error `sql.ErrNoRows` indicates that the query returned no
        rows. Typically that error is worth replacing with more specific text,
        such as “no such album” here.

2. Update `main` to call `albumByID`.

    To the end of `func main`, add the following code.

    ```
    // Hard-code ID 2 here to test the query.
    alb, err := albumByID(2)
    if err != nil {
    	log.Fatal(err)
    }
    fmt.Printf("Album found: %v\n", alb)
    ```

    In the new code, you now:

    *   Call the `albumByID` function you added.

    *   Print the album ID returned.

#### Run the code

From the command line in the directory containing main.go, run the code.


```
$ go run .
Connected!
Albums found: [{1 Blue Train John Coltrane 56.99} {2 Giant Steps John Coltrane 63.99}]
Album found: {2 Giant Steps John Coltrane 63.99}
```

Next, you'll add an album to the database.

## Add data {#add_data}

In this section, you'll use Go to execute an SQL `INSERT` statement to add a
new row to the database.

You’ve seen how to use `Query` and `QueryRow` with SQL statements that
return data. To execute SQL statements that _don't_ return data, you use `Exec`.

#### Write the code

1. Beneath `albumByID`, paste the following `addAlbum` function to insert a new
    album in the database, then save the main.go.

    ```
    // addAlbum adds the specified album to the database,
    // returning the album ID of the new entry
    func addAlbum(alb Album) (int64, error) {
    	result, err := db.Exec("INSERT INTO album (title, artist, price) VALUES (?, ?, ?)", alb.Title, alb.Artist, alb.Price)
    	if err != nil {
    		return 0, fmt.Errorf("addAlbum: %v", err)
    	}
    	id, err := result.LastInsertId()
    	if err != nil {
    		return 0, fmt.Errorf("addAlbum: %v", err)
    	}
    	return id, nil
    }
    ```

    In this code, you:

    *   Use [`DB.Exec`](https://pkg.go.dev/database/sql#DB.Exec) to
        execute an `INSERT` statement.

        Like `Query`, `Exec` takes an SQL statement followed
        by parameter values for the SQL statement.

    *   Check for an error from the attempt to `INSERT`.

    *   Retrieve the ID of the inserted database row using
        [`Result.LastInsertId`](https://pkg.go.dev/database/sql#Result.LastInsertId).

    *   Check for an error from the attempt to retrieve the ID.

2. Update `main` to call the new `addAlbum` function.

    To the end of `func main`, add the following code.

    ```
    albID, err := addAlbum(Album{
    	Title:  "The Modern Sound of Betty Carter",
    	Artist: "Betty Carter",
    	Price:  49.99,
    })
    if err != nil {
    	log.Fatal(err)
    }
    fmt.Printf("ID of added album: %v\n", albID)
    ```

    In the new code, you now:

    *   Call `addAlbum` with a new album, assigning the ID of the album you're
        adding to an `albID` variable.

#### Run the code

From the command line in the directory containing main.go, run the code.

```
$ go run .
Connected!
Albums found: [{1 Blue Train John Coltrane 56.99} {2 Giant Steps John Coltrane 63.99}]
Album found: {2 Giant Steps John Coltrane 63.99}
ID of added album: 5
```

## Conclusion {#conclusion}

Congratulations! You've just used Go to perform simple actions with a
relational database.

Suggested next topics:

*   Take a look at the data access guide, which includes more information
    about the subjects only touched on here.

*   If you're new to Go, you'll find useful best practices described in
    [Effective Go](/doc/effective_go) and [How to write Go code](/doc/code).

*   The [Go Tour](/tour/) is a great step-by-step
    introduction to Go fundamentals.

## Completed code {#completed_code}

This section contains the code for the application you build with this tutorial.

```
package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"

	"github.com/go-sql-driver/mysql"
)

var db *sql.DB

type Album struct {
	ID     int64
	Title  string
	Artist string
	Price  float32
}

func main() {
	// Capture connection properties.
	cfg := mysql.NewConfig()
	cfg.User = os.Getenv("DBUSER")
	cfg.Passwd = os.Getenv("DBPASS")
	cfg.Net = "tcp"
	cfg.Addr = "127.0.0.1:3306"
	cfg.DBName = "recordings"

	// Get a database handle.
	var err error
	db, err = sql.Open("mysql", cfg.FormatDSN())
	if err != nil {
		log.Fatal(err)
	}

	pingErr := db.Ping()
	if pingErr != nil {
		log.Fatal(pingErr)
	}
	fmt.Println("Connected!")

	albums, err := albumsByArtist("John Coltrane")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Albums found: %v\n", albums)

	// Hard-code ID 2 here to test the query.
	alb, err := albumByID(2)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Album found: %v\n", alb)

	albID, err := addAlbum(Album{
		Title:  "The Modern Sound of Betty Carter",
		Artist: "Betty Carter",
		Price:  49.99,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("ID of added album: %v\n", albID)
}

// albumsByArtist queries for albums that have the specified artist name.
func albumsByArtist(name string) ([]Album, error) {
	// An albums slice to hold data from returned rows.
	var albums []Album

	rows, err := db.Query("SELECT * FROM album WHERE artist = ?", name)
	if err != nil {
		return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
	}
	defer rows.Close()
	// Loop through rows, using Scan to assign column data to struct fields.
	for rows.Next() {
		var alb Album
		if err := rows.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {
			return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
		}
		albums = append(albums, alb)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)
	}
	return albums, nil
}

// albumByID queries for the album with the specified ID.
func albumByID(id int64) (Album, error) {
	// An album to hold data from the returned row.
	var alb Album

	row := db.QueryRow("SELECT * FROM album WHERE id = ?", id)
	if err := row.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {
		if err == sql.ErrNoRows {
			return alb, fmt.Errorf("albumsById %d: no such album", id)
		}
		return alb, fmt.Errorf("albumsById %d: %v", id, err)
	}
	return alb, nil
}

// addAlbum adds the specified album to the database,
// returning the album ID of the new entry
func addAlbum(alb Album) (int64, error) {
	result, err := db.Exec("INSERT INTO album (title, artist, price) VALUES (?, ?, ?)", alb.Title, alb.Artist, alb.Price)
	if err != nil {
		return 0, fmt.Errorf("addAlbum: %v", err)
	}
	id, err := result.LastInsertId()
	if err != nil {
		return 0, fmt.Errorf("addAlbum: %v", err)
	}
	return id, nil
}
```
