Avvio rapido: usare Golang per eseguire query su un database nel database SQL di Azure o nell'istanza gestita di SQL di Azure

Si applica a:Database SQL di AzureIstanza gestita di SQL di Azure

In questa guida di avvio rapido si userà il linguaggio di programmazione Golang per la connessione a un database nel database SQL di Azure o nell'istanza gestita di SQL di Azure con il driver go-mssqldb. L'esempio esegue query modificando i dati con istruzioni Transact-SQL (T-SQL) esplicite. Golang è un linguaggio di programmazione open source che consente di creare facilmente software semplice, affidabile ed efficiente.

Prerequisiti

Per completare l'esercitazione introduttiva, sono necessari gli elementi seguenti:

Recuperare le informazioni di connessione del server

Ottenere le informazioni di connessione necessarie per connettersi al database. Nelle procedure successive saranno necessari il nome completo del server o il nome host, il nome del database e le informazioni di accesso.

  1. Accedere al portale di Azure.

  2. Passare alla pagina Database SQL o Istanze gestite di SQL.

  3. Nella pagina Panoramica verificare il nome completo del server accanto a Nome server per il database nel database SQL di Azure o il nome del server completo (o l'indirizzo IP) accanto a Host per un'istanza gestita di SQL di Azure o di SQL Server in una macchina virtuale di Azure. Per copiare il nome del server o il nome host, passare il puntatore su di esso e selezionare l'icona Copia.

Nota

Per le informazioni di connessione per SQL Server in una macchina virtuale di Azure, vedere Connettersi a un'istanza di SQL Server.

Creare una nuova cartella per il progetto Golang e relative dipendenze

  1. Dal terminale creare una nuova cartella di progetto denominata SqlServerSample.

    mkdir SqlServerSample
    

Creare dati di esempio

  1. Nell’editor di testo, all'interno della cartella SqlServerSample, creare un file chiamato CreateTestData.sql. Nel file incollare questo codice T-SQL, che crea uno schema e una tabella e inserisce alcune righe.

    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. Nel prompt dei comandi passare a SqlServerSample e usare sqlcmd per connettersi al database ed eseguire lo script SQL di Azure appena creato. Sostituire i valori relativi al server e al database con quelli appropriati.

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

Inserire il codice per eseguire query sul database

  1. Creare un file denominato sample.go nella cartella SqlServerSample.

  2. Incollare questo codice nel file. Aggiungere i valori per il server e il database Questo esempio usa i metodi Context di Golang per assicurarsi che sia presente una connessione attiva.

    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()
    }
    

Ottenere le dipendenze di progetto Golang ed eseguire il codice

  1. Nel prompt dei comandi passare a SqlServerSample e installare il driver di SQL Server per Go eseguendo i comandi seguenti.

    go mod init SqlServerSample
    go mod tidy
    
  2. Nel prompt dei comandi, eseguire il seguente comando:

    az login
    go run sample.go
    
  3. Verificare l'output.

    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.