クイック スタート:Golang を使用して Azure SQL Database または Azure SQL Managed Instance 内のデータベースに対してクエリを実行する

適用対象:Azure SQL データベースAzure SQL Managed Instance

このクイック スタートでは、Golang プログラミング言語を使用して、go-mssqldb ドライバーで Azure SQL データベースまたは Azure SQL Managed Instance 内のデータベースに接続します。 このサンプルでは、明示的な Transact-SQL (T-SQL) ステートメントを使用してデータを照会および変更します。 Golang は、シンプルで信頼性と効率性の高いソフトウェアを簡単に構築できるオープン ソース プログラミング言語です。

前提条件

このクイック スタートを完了するには、次のものが必要です。

サーバーの接続情報を取得する

データベースに接続するために必要な接続情報を取得します。 後の手順で、完全修飾サーバー名またはホスト名、データベース名、およびログイン情報が必要になります。

  1. Azure portal にサインインします。

  2. [SQL Database] または [SQL Managed Instance] ページに移動します。

  3. [概要] ページで、Azure SQL Database 内のデータベースの [サーバー名] の横にある完全修飾サーバー名、または Azure SQL Managed Instance または Azure VM 上の SQL Server の [ホスト] の横にある完全修飾サーバー名 (または IP アドレス) を確認します。 サーバー名またはホスト名をコピーするには、名前をポイントして [コピー] アイコンを選択します。

Note

Azure VM 上の SQL Server の接続情報については、SQL Server インスタンスへの接続に関するページをご覧ください。

Golang プロジェクトと依存関係用の新しいフォルダーを作成する

  1. ターミナルから、SqlServerSample という名前の新しいプロジェクト フォルダーを作成します。

    mkdir SqlServerSample
    

サンプル データの作成

  1. CreateTestData.sql フォルダー内に、SqlServerSample という新しいテキスト ファイルを作成します。 そのファイルに、次の T-SQL コードを貼り付けます。このコードは、スキーマとテーブルを作成し、数行を挿入します。

    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'Astrid', N'Germany');
    GO
    
    SELECT * FROM TestSchema.Employees;
    GO
    
  2. コマンド プロンプトで、SqlServerSample に移動し、sqlcmd を使用してデータベースに接続し、新しく作成した Azure SQL スクリプトを実行します。 サーバー、データベースを適切な値に置き換えてください。

    az login
    sqlcmd -S <your_server>.database.windows.net -G -d <your_database> -i ./CreateTestData.sql
    

データベースに対してクエリを実行するコードを挿入する

  1. sample.go フォルダー内に SqlServerSample という名前のファイルを作成します。

  2. そのファイルに、以下のコードを貼り付けます。 サーバーおよびデータベースの値を追加します。 この例では、Golang コンテキスト メソッドを使用して、アクティブな接続があることを確認します。

    package main
    
    import (
        "github.com/microsoft/go-mssqldb/azuread"
        "database/sql"
        "context"
        "log"
        "fmt"
        "errors"
    )
    
    var db *sql.DB
    
    var server = "<your_server.database.windows.net>"
    var port = 1433
    var database = "<your_database>"
    
    func main() {
        // Build connection string
        connString := fmt.Sprintf("server=%s;port=%d;database=%s;fedauth=ActiveDirectoryDefault;", server, port, database)
    
        var err error
    
        // Create connection pool
            db, err = sql.Open(azuread.DriverName, 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 isNull(SCOPE_IDENTITY(), -1);
        `
    
        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()
    }
    

Golang プロジェクトの依存関係を取得し、コードを実行する

  1. コマンド プロンプトで SqlServerSample に移動し、次のコマンドを実行して、Go 用の SQL Server ドライバーをインストールします。

    go mod init SqlServerSample
    go mod tidy
    
  2. コマンド プロンプトで、次のコマンドを実行します。

    az login
    go run sample.go
    
  3. 出力を検証します。

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