Quickstart: Use Golang to query a database in Azure SQL Database or Azure SQL Managed Instance

APPLIES TO: yesAzure SQL Database yesAzure SQL Managed Instance

In this quickstart, you'll use the Golang programming language to connect to a database in Azure SQL Database or Azure SQL Managed Instance. You'll then run Transact-SQL statements to query and modify data. Golang is an open-source programming language that makes it easy to build simple, reliable, and efficient software.

Prerequisites

To complete this quickstart, you need:

Get server connection information

Get the connection information you need to connect to the database. You'll need the fully qualified server name or host name, database name, and login information for the upcoming procedures.

  1. Sign in to the Azure portal.

  2. Navigate to the SQL Databases or SQL Managed Instances page.

  3. On the Overview page, review the fully qualified server name next to Server name for a database in Azure SQL Database or the fully qualified server name (or IP address) next to Host for an Azure SQL Managed Instance or SQL Server on Azure VM. To copy the server name or host name, hover over it and select the Copy icon.

Note

For connection information for SQL Server on Azure VM, see Connect to a SQL Server instance.

Create Golang project and dependencies

  1. From the terminal, create a new project folder called SqlServerSample.

    mkdir SqlServerSample
    
  2. Navigate to SqlServerSample and install the SQL Server driver for Go.

    cd SqlServerSample
    go get github.com/denisenkom/go-mssqldb
    go install github.com/denisenkom/go-mssqldb
    

Create sample data

  1. In a text editor, create a file called CreateTestData.sql in the SqlServerSample folder. In the file, paste this T-SQL code, which creates a schema, table, and inserts a few rows.

    CREATE SCHEMA TestSchema;
    GO
    
    CREATE TABLE TestSchema.Employees (
      Id       INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
      Name     NVARCHAR(50),
      Location NVARCHAR(50)
    );
    GO
    
    INSERT INTO TestSchema.Employees (Name, Location) VALUES
      (N'Jared',  N'Australia'),
      (N'Nikita', N'India'),
      (N'Tom',    N'Germany');
    GO
    
    SELECT * FROM TestSchema.Employees;
    GO
    
  2. Use sqlcmd to connect to the database and run your newly created Azure SQL script. Replace the appropriate values for your server, database, username, and password.

    sqlcmd -S <your_server>.database.windows.net -U <your_username> -P <your_password> -d <your_database> -i ./CreateTestData.sql
    

Insert code to query the database

  1. Create a file named sample.go in the SqlServerSample folder.

  2. In the file, paste this code. Add the values for your server, database, username, and password. This example uses the Golang context methods to make sure there's an active connection.

    package main
    
    import (
        _ "github.com/denisenkom/go-mssqldb"
        "database/sql"
        "context"
        "log"
        "fmt"
        "errors"
    )
    
    var db *sql.DB
    
    var server = "<your_server.database.windows.net>"
    var port = 1433
    var user = "<your_username>"
    var password = "<your_password>"
    var database = "<your_database>"
    
    func main() {
        // Build connection string
        connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;",
            server, user, password, port, database)
    
        var err error
    
        // Create connection pool
        db, err = sql.Open("sqlserver", connString)
        if err != nil {
            log.Fatal("Error creating connection pool: ", err.Error())
        }
        ctx := context.Background()
        err = db.PingContext(ctx)
        if err != nil {
            log.Fatal(err.Error())
        }
        fmt.Printf("Connected!\n")
    
        // Create employee
        createID, err := CreateEmployee("Jake", "United States")
        if err != nil {
            log.Fatal("Error creating Employee: ", err.Error())
        }
        fmt.Printf("Inserted ID: %d successfully.\n", createID)
    
        // Read employees
        count, err := ReadEmployees()
        if err != nil {
            log.Fatal("Error reading Employees: ", err.Error())
        }
        fmt.Printf("Read %d row(s) successfully.\n", count)
    
        // Update from database
        updatedRows, err := UpdateEmployee("Jake", "Poland")
        if err != nil {
            log.Fatal("Error updating Employee: ", err.Error())
        }
        fmt.Printf("Updated %d row(s) successfully.\n", updatedRows)
    
        // Delete from database
        deletedRows, err := DeleteEmployee("Jake")
        if err != nil {
            log.Fatal("Error deleting Employee: ", err.Error())
        }
        fmt.Printf("Deleted %d row(s) successfully.\n", deletedRows)
    }
    
    // CreateEmployee inserts an employee record
    func CreateEmployee(name string, location string) (int64, error) {
        ctx := context.Background()
        var err error
    
        if db == nil {
            err = errors.New("CreateEmployee: db is null")
            return -1, err
        }
    
        // Check if database is alive.
        err = db.PingContext(ctx)
        if err != nil {
            return -1, err
        }
    
        tsql := "INSERT INTO TestSchema.Employees (Name, Location) VALUES (@Name, @Location); select convert(bigint, SCOPE_IDENTITY());"
    
        stmt, err := db.Prepare(tsql)
        if err != nil {
           return -1, err
        }
        defer stmt.Close()
    
        row := stmt.QueryRowContext(
            ctx,
            sql.Named("Name", name),
            sql.Named("Location", location))
        var newID int64
        err = row.Scan(&newID)
        if err != nil {
            return -1, err
        }
    
        return newID, nil
    }
    
    // ReadEmployees reads all employee records
    func ReadEmployees() (int, error) {
        ctx := context.Background()
    
        // Check if database is alive.
        err := db.PingContext(ctx)
        if err != nil {
            return -1, err
        }
    
        tsql := fmt.Sprintf("SELECT Id, Name, Location FROM TestSchema.Employees;")
    
        // Execute query
        rows, err := db.QueryContext(ctx, tsql)
        if err != nil {
            return -1, err
        }
    
        defer rows.Close()
    
        var count int
    
        // Iterate through the result set.
        for rows.Next() {
            var name, location string
            var id int
    
            // Get values from row.
            err := rows.Scan(&id, &name, &location)
            if err != nil {
                return -1, err
            }
    
            fmt.Printf("ID: %d, Name: %s, Location: %s\n", id, name, location)
            count++
        }
    
        return count, nil
    }
    
    // UpdateEmployee updates an employee's information
    func UpdateEmployee(name string, location string) (int64, error) {
        ctx := context.Background()
    
        // Check if database is alive.
        err := db.PingContext(ctx)
        if err != nil {
            return -1, err
        }
    
        tsql := fmt.Sprintf("UPDATE TestSchema.Employees SET Location = @Location WHERE Name = @Name")
    
        // Execute non-query with named parameters
        result, err := db.ExecContext(
            ctx,
            tsql,
            sql.Named("Location", location),
            sql.Named("Name", name))
        if err != nil {
            return -1, err
        }
    
        return result.RowsAffected()
    }
    
    // DeleteEmployee deletes an employee from the database
    func DeleteEmployee(name string) (int64, error) {
        ctx := context.Background()
    
        // Check if database is alive.
        err := db.PingContext(ctx)
        if err != nil {
            return -1, err
        }
    
        tsql := fmt.Sprintf("DELETE FROM TestSchema.Employees WHERE Name = @Name;")
    
        // Execute non-query with named parameters
        result, err := db.ExecContext(ctx, tsql, sql.Named("Name", name))
        if err != nil {
            return -1, err
        }
    
        return result.RowsAffected()
    }
    

Run the code

  1. At the command prompt, run the following command.

    go run sample.go
    
  2. Verify the output.

    Connected!
    Inserted ID: 4 successfully.
    ID: 1, Name: Jared, Location: Australia
    ID: 2, Name: Nikita, Location: India
    ID: 3, Name: Tom, Location: Germany
    ID: 4, Name: Jake, Location: United States
    Read 4 row(s) successfully.
    Updated 1 row(s) successfully.
    Deleted 1 row(s) successfully.
    

Next steps