Migreren naar go-mssqldb vanuit andere drivers

Deze gids helpt Go-ontwikkelaars migreren van PostgreSQL, MySQL en andere databasedrivers naar go-mssqldb SQL Server. Het behandelt verschillen in SQL-syntaxis, driver-specifieke wijzigingen en equivalente patronen voor veelvoorkomende bewerkingen.

Note

In de voorbeelden in dit artikel wordt gebruikgemaakt van de AdventureWorks2025-voorbeelddatabase.

Waarom migreren naar SQL Server met go-mssqldb

Feature SQL Server met go-mssqldb
Bedrijfsbeveiliging Altijd versleuteld, beveiliging op rijniveau, dynamische datamaskering, transparante data-encryptie (TDE).
Authentication Microsoft Entra ID (voorheen Azure AD), beheerde identiteit, Windows authentication, Kerberos.
Azure-integratie Native ondersteuning van Azure SQL Database met automatische encryptie, wachtwoordloze verbindingen en failover-afhandeling.
Performance Kolomopslagindexen, in-memory OLTP, queryopslag voor automatische plancorrectie.
Gegevensformaten Ingebouwde JSON- en XML-ondersteuning met server-side indexering en query.
Tooling SQL Server Management Studio (SSMS), Azure Data Studio, Visual Studio Code SQL-extensies.

Checklist voor migratieoverwegingen

Bekijk deze punten voordat je begint met het overzetten van queries regel voor regel:

Consideratie Wat u moet wijzigen
De placeholdersyntaxis verschilt van die van veel Go-drivers. Vervang ?, $1 en vergelijkbare placeholders door @name of @p1, en geef waar passend sql.Named()-argumenten door.
LastInsertId() wordt niet ondersteund. Gebruik OUTPUT INSERTED.<column> of SELECT SCOPE_IDENTITY() in plaats daarvan.
Go-waarden string worden standaard gemapt op Unicode-types. Verwacht nvarchar semantiek, tenzij je een driver-specifiek type kiest, zoals mssql.VarChar voor niet-Unicode-data.
Tijdelijke tabellen zijn beperkt tot de fysieke verbinding. Houd de logica voor het maken en gebruiken van tijdelijke tabellen op dezelfde verbinding of binnen dezelfde transactie als latere instructies van die tabel afhankelijk zijn.
Microsoft Entra-authenticatie gebruikt een andere driverregistratie. Importeergithub.com/microsoft/go-mssqldb/azuread, gebruik sql.Open("azuresql", ...), en stel Azure SQL TLS-opties expliciet in met encrypt=true&TrustServerCertificate=false.

Voor diepere richtlijnen over deze gebieden, zie Queries en statements, Beperkingen, Datatype-mappings, Microsoft Entra ID-authenticatie en Probleemoplossing.

Migreren vanaf lib/pq (PostgreSQL)

Verander de import en de drivernaam

Vervang de lib/pq import en de drivernaam door go-mssqldb:

import _ "github.com/lib/pq"
db, err := sql.Open("postgres", connString)

// After (SQL Server with go-mssqldb):
import _ "github.com/microsoft/go-mssqldb"
db, err := sql.Open("sqlserver", connString)

Verander het formaat van de verbindingsreeks

Converteer het PostgreSQL sleutelwaardeformaat naar een SQL Server URL:

// lib/pq connection string:
"host=<server> port=5432 user=<user> password=<password> dbname=AdventureWorks2025 sslmode=require"

// go-mssqldb connection string:
"sqlserver://<user>:<password>@<server>:1433?database=AdventureWorks2025&encrypt=true"

Veranderparameter tijdelijke houders

PostgreSQL gebruikt $1, $2 positionele plaatsvervangers. SQL Server gebruikt benoemde parameters met@:

// PostgreSQL (lib/pq):
db.QueryContext(ctx, "SELECT * FROM users WHERE id = $1 AND status = $2", id, status)

// SQL Server (go-mssqldb):
db.QueryContext(ctx, "SELECT ProductID, Name FROM Production.Product WHERE ProductID = @id AND Color = @color",
    sql.Named("id", id),
    sql.Named("color", color))

SQL-syntaxiswijzigingen

Operation PostgreSQL SQL Server
Automatisch verhogen SERIAL of GENERATED ALWAYS AS IDENTITY IDENTITY(1,1)
Haal de ingevoegde ID op RETURNING id OUTPUT INSERTED.id of SELECT SCOPE_IDENTITY()
Booleaanse waardetype BOOLEAN BIT
Tekenreeks samenvoeging \|\| + of CONCAT()
Huidige tijdstempel NOW() of CURRENT_TIMESTAMP GETUTCDATE() of SYSDATETIMEOFFSET()
Beperk rijen LIMIT 10 OFFSET 20 OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
Stringtype TEXT of VARCHAR NVARCHAR(MAX) of NVARCHAR(n)
JSON-extractie column->>'key' JSON_VALUE(column, '$.key')
Upsert INSERT ... ON CONFLICT DO UPDATE MERGE verklaring
Arraytype INTEGER[] Geen ingebouwde arrays. Gebruik tabelparameters.
Hoofdlettergevoelig Maakt standaard onderscheid tussen hoofdletters en kleine letters Standaard is het niet hoofdlettergevoelig (hangt af van de samenstelling).

Haal de ingevoegde ID

Vervang de RETURNING clausule van PostgreSQL door die OUTPUT van SQL Server:

var id int
err := db.QueryRowContext(ctx,
    "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id",
    name, email).Scan(&id)

// SQL Server (go-mssqldb) using OUTPUT:
var id int
err := db.QueryRowContext(ctx,
    "INSERT INTO HumanResources.Department (Name, GroupName) OUTPUT INSERTED.DepartmentID VALUES (@name, @groupName)",
    sql.Named("name", name),
    sql.Named("groupName", groupName)).Scan(&id)

Pagination

Vervang de syntaxis LIMIT/OFFSET door de syntaxis OFFSET/FETCH NEXT.

// PostgreSQL:
"SELECT * FROM employees ORDER BY id LIMIT $1 OFFSET $2"

// SQL Server (requires ORDER BY):
"SELECT ProductID, Name, ListPrice FROM Production.Product ORDER BY ProductID OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY"

Migreren vanaf pgx (PostgreSQL)

De pgx driver gebruikt zijn eigen verbindingspool en API die verschillen van database/sql. Om te migreren, schakel over naar de standaardinterface database/sql .

Overstap van pgx pool naar database/sql

Vervang de pgxpool API door de standaardinterface database/sql .

// Before (pgx):
import "github.com/jackc/pgx/v5/pgxpool"
pool, err := pgxpool.New(ctx, "postgres://user:pass@<server>:5432/AdventureWorks2025")
defer pool.Close()
rows, err := pool.Query(ctx, "SELECT * FROM users WHERE id = $1", id)

// After (go-mssqldb with database/sql):
import (
    "database/sql"
    _ "github.com/microsoft/go-mssqldb"
)
db, err := sql.Open("sqlserver", "sqlserver://user:pass@<server>:1433?database=AdventureWorks2025")
defer db.Close()
rows, err := db.QueryContext(ctx,
    "SELECT ProductID, Name FROM Production.Product WHERE ProductID = @id", sql.Named("id", id))

Vervang pgx-specifieke functies

PGX-functie go-mssqldb equivalent
pgx.CollectRows Handmatige rows.Next() en rows.Scan()-lus.
pgx.RowToStructByName Handmatig rows.Scan naar velden van een struct.
Batchqueries (pgx.Batch) Meerdere ExecContext oproepen of opgeslagen procedures.
COPY FROM voor bulk-inzetstukken mssql.CopyIn voor bulkinvoeging.
pgx.ConnConfig msdsn.Config of op URL's gebaseerde verbindingsreeksen.
pgxpool.Pool sql.DB met SetMaxOpenConns en SetMaxIdleConns.

Migreren van go-sql-driver/mysql (MySQL)

Verwissel de MySQL-import en de drivernaam

Vervang de MySQL-import en drivernaam door go-mssqldb.

// Before (MySQL):
import _ "github.com/go-sql-driver/mysql"
db, err := sql.Open("mysql", connString)

// After (SQL Server):
import _ "github.com/microsoft/go-mssqldb"
db, err := sql.Open("sqlserver", connString)

Converteer het MySQL DSN-formaat

Converteer het MySQL DSN-formaat naar een SQL Server-URL.

// MySQL DSN:
"user:password@tcp(<server>:3306)/AdventureWorks2025?tls=true"

// go-mssqldb URL:
"sqlserver://user:password@<server>:1433?database=AdventureWorks2025&encrypt=true"

Vervang vraagteken-plaatsaanduidingen

MySQL gebruikt ? positionele placeholders.

// MySQL:
db.QueryContext(ctx, "SELECT * FROM users WHERE id = ? AND status = ?", id, status)

// SQL Server:
db.QueryContext(ctx, "SELECT ProductID, Name FROM Production.Product WHERE ProductID = @id AND Color = @color",
    sql.Named("id", id),
    sql.Named("color", color))

Vergelijk de syntaxis van MySQL en SQL Server

Operation MySQL SQL Server
Automatisch verhogen AUTO_INCREMENT IDENTITY(1,1)
Haal de ingevoegde ID op LAST_INSERT_ID() SCOPE_IDENTITY() of OUTPUT INSERTED.id
Beperk rijen LIMIT 10 OFFSET 20 OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
Huidige tijdstempel NOW() GETUTCDATE()
Als nul IFNULL(expr, default) ISNULL(expr, default) of COALESCE(expr, default)
Snaar lengte LENGTH(str) LEN(str)
Subtekenreeks SUBSTRING(str, start, len) SUBSTRING(str, start, len) (zelfde)
Datumnotatie DATE_FORMAT(d, '%Y-%m-%d') FORMAT(d, 'yyyy-MM-dd') of CONVERT(VARCHAR, d, 23)
Upsert INSERT ... ON DUPLICATE KEY UPDATE MERGE verklaring
Backtick-citatie `column` [column]

Vervang MySQL-specifieke syntaxis

MySQL-syntax SQL Server-equivalent
AUTO_INCREMENT IDENTITY(1,1)
LIMIT n OFFSET m OFFSET m ROWS FETCH NEXT n ROWS ONLY (vereist ORDER BY)

AUTO_INCREMENT naar IDENTITY:

-- MySQL:
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100)
);

-- SQL Server:
CREATE TABLE HumanResources.NewDepartment (
    DepartmentID SMALLINT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(50) NOT NULL
);

LIMIET voor OFFSET/FETCH:

-- MySQL:
SELECT * FROM users LIMIT 10 OFFSET 20;

-- SQL Server:
SELECT ProductID, Name, ListPrice
FROM Production.Product
ORDER BY ProductID
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

Algemene migratiepatronen

Haal de laatst ingevoegde identiteit

Gebruik de OUTPUT clausule of SCOPE_IDENTITY() om de identiteitswaarde van de ingevoegde rij op te halen:

// Pattern 1: OUTPUT clause (recommended, works with batch inserts).
var id int64
err := db.QueryRowContext(ctx,
    "INSERT INTO HumanResources.Department (Name, GroupName) OUTPUT INSERTED.DepartmentID VALUES (@name, @groupName)",
    sql.Named("name", "Engineering"),
    sql.Named("groupName", "Research and Development")).Scan(&id)

// Pattern 2: SCOPE_IDENTITY (works with single-row inserts).
var id int64
err := db.QueryRowContext(ctx,
    "INSERT INTO HumanResources.Department (Name, GroupName) VALUES (@name, @groupName); SELECT SCOPE_IDENTITY()",
    sql.Named("name", "Engineering"),
    sql.Named("groupName", "Research and Development")).Scan(&id)

Tip

Geef de voorkeur aan de OUTPUT clausule boven SCOPE_IDENTITY(). De OUTPUT clausule werkt met batch-inserts en is niet afhankelijk van de volgorde van de instructies.

Upsert (invoegen of bijwerken)

PostgreSQL ON CONFLICT en MySQL ON DUPLICATE KEY UPDATE komen overeen met SQL Server MERGE:

_, err := db.ExecContext(ctx, `
    MERGE HumanResources.Department AS target
    USING (SELECT @id AS DepartmentID, @name AS Name, @groupName AS GroupName) AS source
    ON target.DepartmentID = source.DepartmentID
    WHEN MATCHED THEN
        UPDATE SET Name = source.Name, GroupName = source.GroupName, ModifiedDate = GETDATE()
    WHEN NOT MATCHED THEN
        INSERT (Name, GroupName, ModifiedDate) VALUES (source.Name, source.GroupName, GETDATE());`,
    sql.Named("id", dept.ID),
    sql.Named("name", dept.Name),
    sql.Named("groupName", dept.GroupName))

Bulksgewijs invoeren

Vervang PostgreSQL's COPY of MySQL's LOAD DATA door mssql.CopyIn.

import mssql "github.com/microsoft/go-mssqldb"

stmt, err := db.Prepare(mssql.CopyIn("HumanResources.Department", mssql.BulkOptions{}, "Name", "GroupName", "ModifiedDate"))
if err != nil {
    return err
}

for _, dept := range departments {
    _, err = stmt.Exec(dept.Name, dept.GroupName, time.Now())
    if err != nil {
        return err
    }
}

// Flush the buffer.
_, err = stmt.Exec()
if err != nil {
    return err
}
stmt.Close()

NULL-waarden verwerken

Alle Go-databasedrivers behandelen NULL-waarden op dezelfde manier omdat ze de database/sql types gebruiken.

var color sql.NullString
err := db.QueryRowContext(ctx,
    "SELECT Color FROM Production.Product WHERE ProductID = @id",
    sql.Named("id", 1)).Scan(&color)

if color.Valid {
    fmt.Println(color.String)
} else {
    fmt.Println("NULL")
}

Transactions

Alle Go-database-drivers gebruiken dezelfde database/sql transactie-API.

tx, err := db.BeginTx(ctx, nil)
if err != nil {
    return err
}
defer tx.Rollback()

_, err = tx.ExecContext(ctx,
    "UPDATE Production.ProductInventory SET Quantity = Quantity - @qty WHERE ProductID = @pid AND LocationID = @fromLoc",
    sql.Named("qty", qty),
    sql.Named("pid", productID),
    sql.Named("fromLoc", fromLocationID))
if err != nil {
    return err
}

_, err = tx.ExecContext(ctx,
    "UPDATE Production.ProductInventory SET Quantity = Quantity + @qty WHERE ProductID = @pid AND LocationID = @toLoc",
    sql.Named("qty", qty),
    sql.Named("pid", productID),
    sql.Named("toLoc", toLocationID))
if err != nil {
    return err
}

return tx.Commit()

Controlelijst voor migratie

Stap Action
Het stuurprogramma installeren go get github.com/microsoft/go-mssqldb
Importen wijzigen Vervang de oude driverimport door _ "github.com/microsoft/go-mssqldb".
Verbindingsreeksen bijwerken Wijzigen naar SQL Server URL-formaat: sqlserver://user:pass@host?database=db.
Vervang plaatsaanduidingen voor parameters Verander $1/$2 of ? met .@namesql.Named
SQL-syntax bijwerken Verander LIMIT/OFFSET, RETURNING, NOW(), , SERIALen andere database-specifieke SQL.
Vervang bulkbewerkingen Verander COPY of LOAD DATA naar mssql.CopyIn.
Schema-DDL bijwerken Verander SERIAL/AUTO_INCREMENT naar IDENTITY, TEXT naar NVARCHAR, BOOLEAN naar .BIT
Test alle zoekopdrachten Voer je testsuite uit tegen een SQL Server-instantie om syntaxisverschillen te detecteren.
Versleuteling configureren Voeg encrypt=true (of vertrouw op Azure auto-detectie) voor productie.
Authenticatie instellen Configureer Microsoft Entra ID voor Azure, of SQL Server-authenticatie voor on-premises.