快速入門:使用 Golang 查詢 Azure SQL 資料庫或 Azure SQL 受控執行個體資料庫

適用於:Azure SQL 資料庫Azure SQL 受控執行個體

在此快速入門中,您將使用 Golang 程式設計語言,透過 go-mssqldb 驅動程式連線至 Azure SQL 資料庫或 Azure SQL 受控執行個體資料庫。 範例使用明確的 Transact-SQL (T-SQL) 陳述式來查詢和修改資料。 Golang 是開放原始碼程式設計語言,可讓您輕鬆地建置簡單、可靠、高效的軟體。

必要條件

若要完成本快速入門,您需要:

取得伺服器連線資訊

取得連線到資料庫所需的連線資訊。 在後續程序中,您將需要完整的伺服器名稱或主機名稱、資料庫名稱和登入資訊。

  1. 登入 Azure 入口網站

  2. 瀏覽至 [SQL Database] 或 [SQL 受控執行個體] 頁面。

  3. 在 [概觀] 頁面上,針對 Azure SQL 資料庫中的資料庫檢閱 [伺服器名稱] 旁的完整伺服器名稱,若為 Azure SQL 受控執行個體或 Azure VM 上的 SQL Server,則檢閱 [主機] 旁的完整伺服器名稱 (或 IP 位址)。 若要複製伺服器名稱或主機名稱,請將滑鼠暫留在其上方,然後選取 [複製] 圖示。

注意

如需 Azure VM 上的 SQL Server 連線資訊,請參閱連線到 SQL Server 執行個體

建立 Golang 專案和相依項的新資料夾

  1. 從終端機建立名為 SqlServerSample 的新專案資料夾。

    mkdir SqlServerSample
    

建立範例資料

  1. 透過文字編輯器在 SqlServerSample 資料夾中建立名為 CreateTestData.sql 的檔案。 在檔案中,貼上此 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.