Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento průvodce pomáhá vývojářům Go migrovat z PostgreSQL, MySQL a dalších ovladačů databáze na go-mssqldb SQL Server. Zahrnuje rozdíly v syntaxi SQL, změny specifické pro ovladače a ekvivalentní vzory pro běžné operace.
Note
Příklady v tomto článku jsou porovnány s databází AdventureWorks2025 .
Proč migrovat na SQL Server s go-mssqldb
| funkce | SQL Server pro go-mssqldb |
|---|---|
| Zabezpečení podniku | Vždy šifrováno, bezpečnost na úrovni řádků, dynamické maskování dat, transparentní šifrování dat (TDE). |
| Autentizace | Microsoft Entra ID (dříve Azure AD), managed identity, Windows authentication, Kerberos. |
| integrace Azure | Nativní podpora Azure SQL Database s automatickým šifrováním, bezheslovými připojeními a řešením failoveru. |
| Performance | Sloupcové indexy, OLTP v paměti, úložiště dotazů pro automatické opravy plánu. |
| Formáty dat | Vestavěná podpora JSON a XML s indexováním a dotazováním na straně serveru. |
| Tooling | SQL Server Management Studio (SSMS), Azure Data Studio, Visual Studio Code SQL extensions. |
Kontrolní seznam pro migraci
Předtím, než začnete přenášet dotazy řádek po řádku, projděte si tyto položky:
| Consideration | Co změnit |
|---|---|
| Syntax zástupných symbolů se liší od syntaxe používané v mnoha ovladačích Go. | Nahraďte ?, $1 a podobné zástupné symboly prvky @name nebo @p1 a poté předejte argumenty sql.Named(), kde je to vhodné. |
LastInsertId() není podporováno. |
Použijte OUTPUT INSERTED.<column> nebo SELECT SCOPE_IDENTITY() místo toho. |
Hodnoty Go string se ve výchozím nastavení mapují na typy Unicode. |
Očekávejte nvarchar sémantiku, pokud si nevyberete typ specifický pro ovladač, například mssql.VarChar pro data mimo Unicode. |
| Dočasné tabulky mají rozsah omezený na fyzické připojení. | Logiku vytváření a používání dočasné tabulky zachovejte ve stejném připojení nebo v rámci stejné transakce, pokud na ní závisejí následné příkazy. |
| Autentizace Microsoft Entra používá jinou registraci ovladače. | Importujte github.com/microsoft/go-mssqldb/azuread, použijte sql.Open("azuresql", ...) a explicitně nastavte možnosti TLS pro Azure SQL pomocí encrypt=true&TrustServerCertificate=false. |
Pro podrobnější informace v těchto oblastech viz Dotazy a příkazy, Omezení, mapování datových typů, autentizace Microsoft Entra ID a Řešení problémů.
Migrace z lib/pq (PostgreSQL)
Změňte import a název ovladače
Nahraďte lib/pq import a název ovladače za 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)
Změňte formát připojovacího řetězce
Převeďte formát klíč–hodnota databáze PostgreSQL na adresu URL serveru SQL Server:
// 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"
Změň zástupce parametrů
PostgreSQL používá poziční zástupné symboly $1, $2. SQL Server používá pojmenované parametry s @:
// 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))
Změny syntaxe SQL
| Operation | PostgreSQL | SQL Server |
|---|---|---|
| Automatické zvyšování |
SERIAL nebo GENERATED ALWAYS AS IDENTITY |
IDENTITY(1,1) |
| Vložte ID | RETURNING id |
OUTPUT INSERTED.id nebo SELECT SCOPE_IDENTITY() |
| Booleovský (logický) typ | BOOLEAN |
BIT |
| Zřetězení řetězců | \|\| |
+ nebo CONCAT() |
| Aktuální časové razítko |
NOW() nebo CURRENT_TIMESTAMP |
GETUTCDATE() nebo SYSDATETIMEOFFSET() |
| Omezit počet řádků | LIMIT 10 OFFSET 20 |
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY |
| Typ řetězce |
TEXT nebo VARCHAR |
NVARCHAR(MAX) nebo NVARCHAR(n) |
| Extrakce JSON | column->>'key' |
JSON_VALUE(column, '$.key') |
| Upsert | INSERT ... ON CONFLICT DO UPDATE |
Prohlášení MERGE |
| Typ pole | INTEGER[] |
Žádná nativní pole. Používejte parametry s tabulkovými hodnotami. |
| Citlivost na velikost písmen | Výchozí rozlišení na velká písmena | Výchozí nastavení není citlivé na velká písmena (záleží na třídění). |
Získejte ID vloženého záznamu
Nahraďte klauzuli PostgreSQL RETURNING klauzulí SQL Serveru OUTPUT:
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
Nahraďte syntaxi LIMIT/OFFSET syntaxí 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"
Migrace z pgx (PostgreSQL)
Ovladač pgx používá vlastní skupinu připojení a API, které se liší od database/sql. Pro migraci přepněte na standardní database/sql rozhraní.
Přechod z pgx poolu na databázové/sql
Nahraďte pgxpool API standardním database/sql rozhraním.
// 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))
Nahraďte funkce specifické pro pgx
| Funkce PGX | Go-mssqldb ekvivalent |
|---|---|
pgx.CollectRows |
Ruční rows.Next() a rows.Scan() smyčka. |
pgx.RowToStructByName |
Ručně rows.Scan do členů struktury. |
Dávkové dotazy (pgx.Batch) |
Vícenásobná volání ExecContext nebo uložené procedury. |
COPY FROM pro hromadné vložení |
mssql.CopyIn pro hromadné vkládání. |
pgx.ConnConfig |
msdsn.Config nebo řetězce spojení založené na URL. |
pgxpool.Pool |
sql.DB s SetMaxOpenConns a SetMaxIdleConns. |
Přechod z go-sql-driver/mysql (MySQL)
Vyměňte import a název ovladače MySQL
Nahraďte import a název ovladače do MySQL za 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)
Převod formátu MySQL DSN
Převeďte formát MySQL DSN na URL SQL Server.
// MySQL DSN:
"user:password@tcp(<server>:3306)/AdventureWorks2025?tls=true"
// go-mssqldb URL:
"sqlserver://user:password@<server>:1433?database=AdventureWorks2025&encrypt=true"
Nahraďte zástupné symboly otazníku
MySQL používá ? poziční zástupné symboly.
// 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))
Porovnejte syntaxi MySQL a SQL Server
| Operation | MySQL | SQL Server |
|---|---|---|
| Automatické zvyšování | AUTO_INCREMENT |
IDENTITY(1,1) |
| Vložte ID | LAST_INSERT_ID() |
SCOPE_IDENTITY() nebo OUTPUT INSERTED.id |
| Omezit počet řádků | LIMIT 10 OFFSET 20 |
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY |
| Aktuální časové razítko | NOW() |
GETUTCDATE() |
| Pokud nulová | IFNULL(expr, default) |
ISNULL(expr, default) nebo COALESCE(expr, default) |
| Délka řetězce | LENGTH(str) |
LEN(str) |
| Podřetězec | SUBSTRING(str, start, len) |
SUBSTRING(str, start, len) (stejné) |
| Formát dat | DATE_FORMAT(d, '%Y-%m-%d') |
FORMAT(d, 'yyyy-MM-dd') nebo CONVERT(VARCHAR, d, 23) |
| Upsert | INSERT ... ON DUPLICATE KEY UPDATE |
Prohlášení MERGE |
| Backtick citace | `column` |
[column] |
Nahraďte syntaxi specifickou pro MySQL
| Syntaxe MySQL | Ekvivalent pro SQL Server |
|---|---|
AUTO_INCREMENT |
IDENTITY(1,1) |
LIMIT n OFFSET m |
OFFSET m ROWS FETCH NEXT n ROWS ONLY (vyžaduje ORDER BY) |
AUTO_INCREMENT do 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
);
LIMIT to 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;
Běžné vzory migrace
Získejte poslední vloženou identitu
Použijte klauzuli OUTPUT nebo SCOPE_IDENTITY() k získání identity vloženého řádku:
// 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
Upřednostňujeme klauzuli OUTPUT před SCOPE_IDENTITY(). Doložka OUTPUT funguje s dávkovým vkládáním a nezávisí na pořadí příkazů.
Upsert (vložit nebo aktualizovat záznam)
PostgreSQL ON CONFLICT a MySQL ON DUPLICATE KEY UPDATE odpovídají v SQL Serveru 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))
Hromadné vložení
Nahraďte PostgreSQL COPY nebo MySQL LOAD DATA za 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()
Zpracovat hodnoty NULL
Všechny ovladače databáze Go zpracovávají hodnoty NULL stejným způsobem, protože používají typy database/sql .
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
Všechny ovladače databáze Go používají stejné database/sql transakční 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()
Kontrolní seznam pro migraci
| Krok | Action |
|---|---|
| Instalace ovladače | go get github.com/microsoft/go-mssqldb |
| Změnit importy | Nahraďte starý import ovladačů za _ "github.com/microsoft/go-mssqldb". |
| Aktualizujte připojovací řetězce | Změna formátu URL na SQL Server: sqlserver://user:pass@host?database=db. |
| Nahraďte zástupce parametrů | Změňte $1/$2 nebo ? na @name pomocí sql.Named. |
| Aktualizovat syntaxi SQL | Změňte LIMIT/OFFSET, RETURNING, NOW(), SERIAL a další SQL specifické pro danou databázi. |
| Nahrazení hromadných operací | Změň COPY nebo LOAD DATA na mssql.CopyIn. |
| Aktualizace schématu DDL | Změňte SERIAL/AUTO_INCREMENT na IDENTITY, TEXT na NVARCHAR, BOOLEAN na .BIT |
| Otestujte všechny dotazy | Spusť testovací sadu na instanci SQL Server, abys zachytil rozdíly v syntaxi. |
| Konfigurace šifrování | Přidejte encrypt=true (nebo se spolehněte na automatické rozpoznání Azure) pro produkční nasazení. |
| Nastavení ověřování | Konfigurujte Microsoft Entra ID pro Azure nebo SQL Server autentizaci pro on-premises. |