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

GoLang调用存储过程时QueryRowContext报错:参数数量不匹配

问题原因及解决方案

核心问题

你遇到的sql: expected 0 arguments, got 2错误,本质是数据库驱动不识别你用的@Email命名参数格式,导致Prepare解析SQL时认为没有需要绑定的参数,但你后续又传入了参数,两者产生冲突。另外,sql.Named的使用需要驱动明确支持,并非所有数据库驱动都兼容这种命名参数写法,且不同数据库的存储过程参数占位符规则存在差异。

针对不同数据库的解决方法

情况1:使用MySQL驱动(github.com/go-sql-driver/mysql)

MySQL驱动不支持@xxx格式的命名参数,也不兼容sql.Named,需改用?作为参数占位符:

func VerifyUser(user User) (*User, string, error) {
    db, ctx := db.GetDB()
    // 改用?作为参数占位符
    query := "CALL usp_GetUserByUsername(?)"

    stmt, err := db.Prepare(query)
    if err != nil {
        log.Errorln("Error in preparing statement. " + err.Error())
        return nil, "Error in preparing statement.", err
    }
    defer stmt.Close()

    // 直接传递参数值,无需sql.Named
    row := stmt.QueryRowContext(ctx, user.Email)

    var retUser User
    err = row.Scan(&retUser.ID, &retUser.Email, &retUser.Password, &retUser.Status)
    if err != nil {
        log.Warningln("Unknown Email: " + user.Email + ". " + err.Error())
        return nil, "Invalid user.", err
    }
    return &retUser, "", nil
}

情况2:使用SQL Server驱动(github.com/microsoft/go-mssqldb)

SQL Server驱动支持命名参数,可调整写法直接调用:

func VerifyUser(user User) (*User, string, error) {
    db, ctx := db.GetDB()
    // 保留存储过程的命名参数写法
    query := "CALL usp_GetUserByUsername(@Email)"

    // 直接用QueryRowContext调用,无需提前Prepare(驱动会自动处理参数绑定)
    row := db.QueryRowContext(ctx, query, sql.Named("Email", user.Email))

    var retUser User
    err := row.Scan(&retUser.ID, &retUser.Email, &retUser.Password, &retUser.Status)
    if err != nil {
        log.Warningln("Unknown Email: " + user.Email + ". " + err.Error())
        return nil, "Invalid user.", err
    }
    return &retUser, "", nil
}

额外注意点

  • 部分数据库驱动对存储过程的Prepare支持有限,直接使用QueryRowContext调用存储过程往往更可靠。
  • 确保你的数据库驱动版本为最新,避免旧版本存在的参数解析bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:33:59