You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSSQL插入报错:Incorrect syntax near '?',数据未写入数据库

解决MSSQL插入时「mssql: Incorrect syntax near '?'」错误及数据未写入问题

核心原因

MSSQL的SQL参数占位符不是?,而是使用**@前缀的命名/位置参数**。Go常用的MSSQL驱动(如github.com/denisenkom/go-mssqldb)不支持?作为占位符,这就是报错的直接原因。

代码中的其他问题

除了占位符错误,你的代码还有几个导致数据未写入却返回成功的问题:

  • 重复调用db.InitialConnection(),可能每次调用都创建新连接,甚至连接未正确复用
  • 完全忽略Exec方法的错误返回,即使插入失败仍返回"add sucess"
  • BindJSON的错误处理不完整,未终止后续逻辑

修改后的代码示例

type CreateAccount struct {
    AccountPassword string `json:"accountPassword" binding:"required"`
    UserName        string `json:"userName" binding:"required"`
}

// SignUp takes a user JSON and stores in DB.
// SignUp             godoc
// @Summary      Create a new user
// @Description  Takes an account JSON and stores it in DB. Return saved JSON.
// @Tags         User
// @Produce      json
// @Param        account  body      models.Account  true  "Account JSON"
// @Success      200   {object}  models.Account
// @Router       /users [post]
func SignUp(c *gin.Context) {
    // 获取数据库连接,仅调用一次
    dtTable := db.InitialConnection()
    if dtTable == nil {
        c.JSON(http.StatusInternalServerError, "数据库连接失败")
        return
    }

    var newUser CreateAccount
    // 绑定JSON并处理错误,绑定失败直接返回
    if err := c.BindJSON(&newUser); err != nil {
        c.JSON(http.StatusBadRequest, "JSON解析失败: "+err.Error())
        return
    }

    account := models.Account{
        AccountPassword: newUser.AccountPassword,
        UserName:        newUser.UserName,
    }

    // 使用MSSQL支持的@占位符,位置参数@1、@2或命名参数@AccountPassword、@UserName均可
    res, err := dtTable.Exec("INSERT INTO Account(accountPassword, userName) VALUES(@1, @2)", account.AccountPassword, account.UserName)
    if err != nil {
        c.JSON(http.StatusInternalServerError, "数据插入失败: "+err.Error())
        return
    }

    // 可选:验证数据是否实际写入
    rowsAffected, _ := res.RowsAffected()
    if rowsAffected == 0 {
        c.JSON(http.StatusInternalServerError, "数据未写入数据库")
        return
    }

    c.JSON(http.StatusOK, "添加成功")
}

关键修改说明

  1. 占位符替换:把?改成@1、@2(位置参数)或命名参数,适配MSSQL驱动要求
  2. 连接处理:仅调用一次InitialConnection(),先判断连接状态,失败直接返回
  3. 错误处理:完整处理BindJSON和Exec的错误,错误时返回对应状态码和信息,不再盲目返回成功
  4. 写入验证:通过RowsAffected()确认是否有数据被插入,进一步确保写入结果

额外建议

  • 不要每次请求都创建新数据库连接,建议初始化全局连接池复用连接,提升性能
  • 生产环境避免直接返回原始错误给前端,可做错误包装,防止泄露数据库细节

内容的提问来源于stack exchange,提问作者user19800025

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 05:24:17