应使用 microsoft/go-mssqldb 驱动,因其稳定活跃、纯 Go 实现且跨平台兼容;安装命令为 go get github.com/microsoft/go-mssqldb,导入需用 _ "github.com/microsoft/go-mssqldb" 触发注册,DSN 示例:server=localhost;user id=sa;password=YourPass123;database=MyDB;encrypt=disable;trustServerCertificate=true;必须调用 db.Ping() 健康检查并重试,合理配置连接池参数(如 SetMaxOpenConns、SetMaxIdleConns、SetConnMaxLifetime)以避免生产环境连接耗尽。

用 sqlserver 驱动而非 odbc 或 mysql 驱动
Go 官方 database/sql 不自带 MSSQL 支持,必须选对驱动。目前最稳定、维护活跃的是 microsoft/go-mssqldb,它的 DSN 格式和行为与其他驱动差异明显。别用 odbc(Windows 依赖重、跨平台麻烦)或误配成 mysql 驱动(会报 driver: unknown driver "mysql" (forgotten import?) 这类误导性错误)。
- 安装命令:
go get github.com/microsoft/go-mssqldb - import 必须包含:
_ "github.com/microsoft/go-mssqldb"(下划线触发 init 注册) - DSN 示例:
server=localhost;user id=sa;password=YourPass123;database=MyDB;encrypt=disable;trustServerCertificate=true——encrypt=disable和trustServerCertificate=true在开发环境必要,否则连不上本地 SQL Server Express
sql.Open 后必须调用 db.Ping() 检查连接有效性
微服务启动时若数据库不可达,sql.Open 不会立即失败(它只做配置解析),真正报错常发生在首次 Query 或 Exec 时,导致服务看似启动成功实则无法处理请求。必须在初始化 DB 实例后显式 Ping 并重试有限次数。
- 不要只写
db, err := sql.Open("sqlserver", dsn)就往下走 - 加一层健康检查逻辑:用
time.AfterFunc或简单 for-loop +time.Sleep重试 3–5 次,每次间隔 1–2 秒 - 若最终
db.Ping()失败,应直接log.Fatal或触发服务启动失败(比如返回 error 给 main 函数),避免“假启动”
注意 datetime2 和 time.Time 的精度兼容性问题
MSSQL 的 datetime2 默认精度是 100ns,而 Go 的 time.Time 在 JSON 序列化或某些 ORM 映射中可能被截断为毫秒,导致写入/查询时时间偏移。这不是 bug,是类型映射默认行为。
- 建表时若业务不需要纳秒级精度,显式用
datetime2(3)(即毫秒级)替代默认datetime2 - 读取时用
rows.Scan(&t)得到的time.Time是完整精度的;但若经由json.Marshal输出,需确认是否启用了time.RFC3339Nano或自定义 marshaler - 使用
sql.NullTime处理可能为 NULL 的时间字段,否则遇到 NULL 会 panic
连接池参数要按微服务负载调,不能沿用本地开发默认值
默认 MaxOpenConns=0(无限制)、MaxIdleConns=2,在高并发微服务中极易打满数据库连接数,引发超时或拒绝连接。MSSQL 对每个登录名的连接数有硬限制(取决于版本和授权),必须主动约束。
立即学习“go语言免费学习笔记(深入)”;
- 设
db.SetMaxOpenConns(20)(根据实例规格和预估 QPS 调整,常见范围 10–50) - 设
db.SetMaxIdleConns(10),避免空闲连接长期占用资源 - 设
db.SetConnMaxLifetime(5 * time.Minute),强制复用老连接前重建,防止因网络中断或防火墙超时导致的 stale connection - 配合 SQL Server 的
sp_who2或 DMV 查询sys.dm_exec_sessions,观察实际连接数分布,验证配置是否生效
真正麻烦的不是连不上,而是连接池参数没调好导致偶发超时、连接堆积、或数据库侧资源耗尽——这些在压测阶段才暴露,但修复成本远高于启动时就配对。


















