golang连接Microsoft SQL Server数据库驱动插件库go-mssqldb的使用

Golang连接Microsoft SQL Server数据库驱动插件库go-mssqldb的使用

安装

需要Go 1.8或更高版本。

使用以下命令安装:

go get github.com/denisenkom/go-mssqldb

连接参数和DSN

推荐的连接字符串使用URL格式:

sqlserver://username:password@host/instance?param1=value&param2=value

常见参数

  • user id - SQL Server认证用户ID或Windows认证用户ID(格式为DOMAIN\User)
  • password - 密码
  • database - 数据库名
  • connection timeout - 连接超时(秒,默认0表示无超时)
  • dial timeout - 拨号超时(秒,默认15)
  • encrypt - 加密选项:
    • disable - 不加密
    • false - 仅登录包加密(默认)
    • true - 全部加密
  • app name - 应用程序名称(默认go-mssqldb)

完整示例

package main

import (
    "database/sql"
    "fmt"
    "log"
    "net/url"
    _ "github.com/denisenkom/go-mssqldb"
)

func main() {
    // 使用URL格式连接
    query := url.Values{}
    query.Add("app name", "MyAppName")
    query.Add("database", "testdb")
    
    u := &url.URL{
        Scheme:   "sqlserver",
        User:     url.UserPassword("username", "password"),
        Host:     "localhost:1433",
        RawQuery: query.Encode(),
    }
    
    db, err := sql.Open("sqlserver", u.String())
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    // 测试连接
    err = db.Ping()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Connected to SQL Server!")
    
    // 执行查询
    rows, err := db.Query("SELECT name FROM sys.databases")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()
    
    for rows.Next() {
        var name string
        if err := rows.Scan(&name); err != nil {
            log.Fatal(err)
        }
        fmt.Println(name)
    }
}

执行存储过程

要执行存储过程,将查询文本设置为过程名称:

var account = "abc"
_, err := db.ExecContext(ctx, "sp_RunMe",
    sql.Named("ID", 123),
    sql.Named("Account", sql.Out{Dest: &account}),
)

从带有结果集的存储过程读取输出参数

要读取带有结果集的存储过程的输出参数,确保在读取输出参数之前读取所有行:

var bitout int64
rows, err := db.QueryContext(ctx, "spwithoutputandrows", sql.Named("bitparam", sql.Out{Dest: &bitout}))
var strrow string
for rows.Next() {
    err = rows.Scan(&strrow)
}
fmt.Printf("bitparam is %d", bitout)

参数

sqlserver驱动使用正常的MS SQL Server语法,并期望SQL查询中的参数采用@Name@p1@pN(序数位置)的形式。

db.QueryContext(ctx, `select * from t where ID = @ID and Name = @p2;`, sql.Named("ID", 6), "Bob")

重要注意事项

  • 不应使用LastInsertId,因为TDS协议的工作方式
  • 可以使用NewConnectorOpenDB
  • Connector.SessionInitSQL可用于在会话重置后设置任何驱动程序特定的会话设置

特性

  • 可与SQL Server 2005或更高版本一起使用
  • 可与Microsoft Azure SQL数据库一起使用
  • 可在所有Go支持的平台上使用(如Linux、Mac OS X和Windows)
  • 支持新的日期/时间类型:date、time、datetime2、datetimeoffset
  • 支持超过8000个字符的字符串参数
  • 支持使用SSL/TLS加密
  • 支持SQL Server和Windows身份验证
  • 支持Windows上的单点登录
  • 支持连接到AlwaysOn可用性组监听器,包括重定向到只读副本
  • 支持查询通知

更多关于golang连接Microsoft SQL Server数据库驱动插件库go-mssqldb的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang连接Microsoft SQL Server数据库驱动插件库go-mssqldb的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-mssqldb连接Microsoft SQL Server数据库

go-mssqldb是Golang连接Microsoft SQL Server的官方推荐驱动,下面详细介绍其使用方法。

安装驱动

首先需要安装go-mssqldb驱动:

go get github.com/denisenkom/go-mssqldb

基本连接示例

package main

import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/denisenkom/go-mssqldb"
)

func main() {
    // 连接字符串格式
    // server=服务器地址;user id=用户名;password=密码;database=数据库名
    connString := "server=localhost;user id=sa;password=your_password;database=testdb;encrypt=disable"
    
    // 打开数据库连接
    db, err := sql.Open("sqlserver", connString)
    if err != nil {
        log.Fatal("连接数据库失败:", err.Error())
    }
    defer db.Close()
    
    // 测试连接
    err = db.Ping()
    if err != nil {
        log.Fatal("无法连接到数据库:", err.Error())
    }
    
    fmt.Println("成功连接到SQL Server数据库")
}

连接参数说明

连接字符串支持以下常用参数:

  • server: 服务器地址(可以是IP或主机名)
  • port: 端口号(默认1433)
  • user id: 用户名
  • password: 密码
  • database: 数据库名
  • encrypt: 是否加密(disable/true/false)
  • connection timeout: 连接超时(秒)
  • dial timeout: 拨号超时(秒)

执行查询

// 查询示例
func queryData(db *sql.DB) {
    rows, err := db.Query("SELECT id, name, age FROM users WHERE age > ?", 18)
    if err != nil {
        log.Fatal("查询失败:", err)
    }
    defer rows.Close()
    
    for rows.Next() {
        var id int
        var name string
        var age int
        err = rows.Scan(&id, &name, &age)
        if err != nil {
            log.Fatal("读取行失败:", err)
        }
        fmt.Printf("ID: %d, Name: %s, Age: %d\n", id, name, age)
    }
    
    if err = rows.Err(); err != nil {
        log.Fatal("遍历结果集出错:", err)
    }
}

执行插入/更新/删除

// 插入数据示例
func insertData(db *sql.DB) {
    result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "张三", 25)
    if err != nil {
        log.Fatal("插入失败:", err)
    }
    
    rowsAffected, err := result.RowsAffected()
    if err != nil {
        log.Fatal("获取影响行数失败:", err)
    }
    
    fmt.Printf("插入成功,影响行数: %d\n", rowsAffected)
}

使用事务

// 事务示例
func transactionExample(db *sql.DB) {
    tx, err := db.Begin()
    if err != nil {
        log.Fatal("开启事务失败:", err)
    }
    
    defer func() {
        if err != nil {
            tx.Rollback()
            return
        }
        tx.Commit()
    }()
    
    // 执行事务中的操作
    _, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", 100, 1)
    if err != nil {
        log.Println("更新账户1失败:", err)
        return
    }
    
    _, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", 100, 2)
    if err != nil {
        log.Println("更新账户2失败:", err)
        return
    }
    
    fmt.Println("事务执行成功")
}

处理NULL值

// 处理可能为NULL的列
func queryWithNull(db *sql.DB) {
    var name sql.NullString
    var age sql.NullInt64
    
    row := db.QueryRow("SELECT name, age FROM users WHERE id = ?", 1)
    err := row.Scan(&name, &age)
    if err != nil {
        log.Fatal("查询失败:", err)
    }
    
    if name.Valid {
        fmt.Println("Name:", name.String)
    } else {
        fmt.Println("Name is NULL")
    }
    
    if age.Valid {
        fmt.Println("Age:", age.Int64)
    } else {
        fmt.Println("Age is NULL")
    }
}

连接池配置

func main() {
    connString := "server=localhost;user id=sa;password=your_password;database=testdb"
    
    db, err := sql.Open("sqlserver", connString)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    // 配置连接池
    db.SetMaxOpenConns(10)    // 最大打开连接数
    db.SetMaxIdleConns(5)     // 最大空闲连接数
    db.SetConnMaxLifetime(time.Hour) // 连接最大存活时间
    
    // 使用数据库...
}

注意事项

  1. 对于Azure SQL Database,连接字符串需要添加;encrypt=true参数
  2. 如果使用Windows身份验证,可以使用;trusted_connection=true代替用户名密码
  3. 在生产环境中,建议将连接字符串配置在环境变量或配置文件中
  4. 长时间运行的应用程序应该处理连接断开的场景,实现重连逻辑

通过以上示例,您应该能够使用go-mssqldb驱动在Golang中连接和操作SQL Server数据库了。

回到顶部