# go-mssqldb Complete Reference for LLMs > Microsoft's official Go driver for SQL Server and Azure SQL Database > Package: github.com/microsoft/go-mssqldb > License: BSD-3-Clause ## Overview This is the recommended driver for connecting Go applications to: - Microsoft SQL Server (2005 and later) - Azure SQL Database - Azure SQL Managed Instance - Azure Synapse Analytics ## Installation ```bash go get github.com/microsoft/go-mssqldb ``` ## Driver Names | Driver | Package | Use Case | |--------|---------|----------| | `sqlserver` | main | Standard connections, use `@param` syntax | | `azuresql` | azuread | Azure AD authentication | | `mssql` | main | **DEPRECATED** - uses `?` syntax | ## Import Patterns ### Standard Connection ```go import ( "database/sql" _ "github.com/microsoft/go-mssqldb" ) db, err := sql.Open("sqlserver", "sqlserver://user:password@localhost:1433?database=mydb") ``` ### Azure AD Authentication ```go import ( "database/sql" "github.com/microsoft/go-mssqldb/azuread" ) // Enable TLS with certificate validation for Azure SQL db, err := sql.Open(azuread.DriverName, "sqlserver://server.database.windows.net?database=mydb&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false") ``` ### Kerberos Authentication (Linux) ```go import ( _ "github.com/microsoft/go-mssqldb" _ "github.com/microsoft/go-mssqldb/integratedauth/krb5" ) db, err := sql.Open("sqlserver", "sqlserver://user@host/instance?authenticator=krb5&krb5-configfile=/etc/krb5.conf") ``` ## Connection String Formats ### URL Format (Recommended) ``` sqlserver://user:password@host:port?database=dbname sqlserver://user:password@host/instance?database=dbname sqlserver://user:password@server.database.windows.net?database=dbname&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false ``` ### ADO Format ``` server=localhost;user id=sa;password=secret;database=mydb server=localhost\SQLEXPRESS;user id=sa;password=secret;database=mydb ``` ### ODBC Format ``` odbc:server=localhost;user id=sa;password=secret;database=mydb ``` ## Connection Parameters | Parameter | Description | Default / Recommendation | |-----------|-------------|---------------------------| | `database` | Database name | - | | `user id` | Username (DOMAIN\User for Windows auth) | - | | `password` | Password | - | | `encrypt` | `true`, `false`, `strict`, `disable` | **Recommended:** `true` (or `strict`) for production | | `TrustServerCertificate` | Skip cert verification | **Recommended:** `false` (validate server certificate) | | `connection timeout` | Seconds (0=no timeout) | 0 | | `app name` | Application name | go-mssqldb | | `authenticator` | `ntlm`, `winsspi`, `krb5` | platform default | > **Security Note**: For production and Azure SQL connections, always set `encrypt=true` and `TrustServerCertificate=false` to ensure encrypted connections with proper server identity verification. ## Query Parameter Syntax **IMPORTANT**: When using the `sqlserver` driver, use `@name` or `@p1, @p2, ...` - NOT `$1` or `?`. The deprecated `mssql` driver supports `?` placeholders via token replacement, but new code should use `sqlserver`. ### Named Parameters ```go rows, err := db.QueryContext(ctx, "SELECT * FROM users WHERE id = @ID AND status = @Status", sql.Named("ID", 123), sql.Named("Status", "active"), ) ``` ### Positional Parameters ```go rows, err := db.QueryContext(ctx, "SELECT * FROM users WHERE id = @p1 AND status = @p2", 123, "active", ) ``` ## Common Operations ### Execute Query ```go rows, err := db.QueryContext(ctx, "SELECT id, name FROM users WHERE active = @p1", true) if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var id int var name string if err := rows.Scan(&id, &name); err != nil { log.Fatal(err) } fmt.Printf("ID: %d, Name: %s\n", id, name) } ``` ### Execute Statement ```go result, err := db.ExecContext(ctx, "UPDATE users SET status = @p1 WHERE id = @p2", "inactive", 123) if err != nil { log.Fatal(err) } rowsAffected, _ := result.RowsAffected() ``` ### Stored Procedure with Output ```go var outputValue string _, err := db.ExecContext(ctx, "sp_MyProcedure", sql.Named("InputParam", "test"), sql.Named("OutputParam", sql.Out{Dest: &outputValue}), ) ``` ### Return Status ```go import mssql "github.com/microsoft/go-mssqldb" var returnStatus mssql.ReturnStatus _, err := db.ExecContext(ctx, "sp_MyProcedure", &returnStatus) fmt.Printf("Return status: %d\n", returnStatus) ``` ### Bulk Copy ```go import mssql "github.com/microsoft/go-mssqldb" txn, _ := db.Begin() stmt, _ := txn.Prepare(mssql.CopyIn("tablename", mssql.BulkOptions{}, "col1", "col2", "col3")) for _, row := range data { stmt.Exec(row.Col1, row.Col2, row.Col3) } stmt.Exec() // Flush remaining rows stmt.Close() txn.Commit() ``` ### Get Last Insert ID (NOT LastInsertId!) ```go // ✅ CORRECT: Use OUTPUT clause var newID int64 err := db.QueryRowContext(ctx, "INSERT INTO users (name) OUTPUT INSERTED.id VALUES (@p1)", "John", ).Scan(&newID) // ✅ CORRECT: Use SCOPE_IDENTITY() err = db.QueryRowContext(ctx, "INSERT INTO users (name) VALUES (@p1); SELECT CAST(SCOPE_IDENTITY() AS bigint)", "John", ).Scan(&newID) // ❌ WRONG: LastInsertId() doesn't work with SQL Server result, _ := db.Exec("INSERT INTO users (name) VALUES (@p1)", "John") id, err := result.LastInsertId() // Returns -1 and an error on Go 1.10+, not supported! ``` ## Azure AD fedauth Values | Value | Description | |-------|-------------| | `ActiveDirectoryDefault` | DefaultAzureCredential chain (recommended) | | `ActiveDirectoryMSI` | Managed Identity | | `ActiveDirectoryServicePrincipal` | Service principal with secret/cert | | `ActiveDirectoryPassword` | Username and password | | `ActiveDirectoryAzCli` | Azure CLI credentials | | `ActiveDirectoryInteractive` | Browser-based interactive | | `ActiveDirectoryDeviceCode` | Device code flow | ## Type Mappings | Go Type | SQL Server Type | |---------|-----------------| | `string` | nvarchar | | `mssql.VarChar` | varchar | | `time.Time` | datetimeoffset or datetime (TDS version dependent) | | `mssql.DateTime1` | datetime | | `civil.Date` | date | | `civil.DateTime` | datetime2 | | `civil.Time` | time | | `mssql.TVP` | table type | | `decimal.Decimal` | decimal | ## Common Mistakes to Avoid 1. **Wrong driver name**: Use `"sqlserver"` not `"mssql"` 2. **Wrong parameter syntax**: Use `@name` or `@p1` not `$1` or `?` 3. **Using LastInsertId()**: Use OUTPUT clause or SCOPE_IDENTITY() instead 4. **Azure AD without package**: Must import `github.com/microsoft/go-mssqldb/azuread` 5. **Missing context**: Always use `QueryContext`/`ExecContext` for timeout control ## Features - SQL Server 2005+ and Azure SQL Database - Windows Authentication, SQL Authentication, Azure AD, Kerberos - Always Encrypted column encryption - Bulk copy operations - Stored procedures with output parameters - Table-valued parameters - Named pipes and shared memory (Windows) - Query notifications - TLS/SSL encryption ## Links - GitHub: https://github.com/microsoft/go-mssqldb - pkg.go.dev: https://pkg.go.dev/github.com/microsoft/go-mssqldb - Wiki: https://github.com/microsoft/go-mssqldb/wiki - Examples: https://github.com/microsoft/go-mssqldb/tree/main/examples