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

Golang使用row.Scan扫描多行结果报错:sql: expected 1 arguments, got 2

问题原因及解决方法

核心问题点

  1. 错误使用QueryRow处理多行结果
    QueryRow仅用于查询单行数据,你的存储过程返回多行结果,用它会导致只读取第一行,且因为结果集有2列,但你传入的是一个切片指针(仅1个参数),触发expected 1 arguments, got 2的参数不匹配错误。

  2. 直接扫描到切片的方式不合法
    Scan()要求传入与结果集列数一一对应的变量指针,不能直接把切片指针传进去,切片需要逐行读取结构体后再填充。

修正后的代码

type Permission struct {
    ID               int    `json:"id"`
    Name             string `json:"name"`
    Description      string `json:"description"`
    ParentResourceID int    `json:"parentResourceId"`
}

func GetResourcesByResourceTypeId(resourceTypeId string) ([]Permission, string, error) {
    db, ctx := db.GetDB()
    query := "CALL usp_GetParentResourceListByResourceTypeID(?)"
    var resourceList []Permission
    
    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()
    
    // 使用Query获取多行结果集,替代QueryRow
    rows, err := stmt.Query(ctx, resourceTypeId)
    if err != nil {
        log.Errorln("Error executing query. " + err.Error())
        return nil, "Error executing query.", err
    }
    defer rows.Close()
    
    // 循环遍历每一行数据
    for rows.Next() {
        var p Permission
        // 存储过程仅返回ID和Name两个字段,对应扫描这两个变量
        err = rows.Scan(&p.ID, &p.Name)
        if err != nil {
            log.Errorln("Error scanning row. " + err.Error())
            return nil, "Error scanning row.", err
        }
        // 结构体中未返回的字段手动设置默认值(可根据业务调整)
        p.Description = ""
        p.ParentResourceID = 0
        resourceList = append(resourceList, p)
    }
    
    // 检查遍历过程中是否出现错误
    if err = rows.Err(); err != nil {
        log.Errorln("Row iteration error. " + err.Error())
        return nil, "Row iteration error.", err
    }
    
    if len(resourceList) == 0 {
        log.Warningln("Resource retrieval failed, ResourceTypeID: " + resourceTypeId + ".")
        return resourceList, "Resource retrieval failed.", nil
    }
    
    return resourceList, "Resource retrieval.", nil
}

额外说明

  • 你的Permission结构体有4个字段,但存储过程仅返回ID和Name,扫描时必须严格对应返回的列数,未返回的字段需要手动设置默认值或按业务逻辑处理。
  • 必须调用rows.Close()释放数据库资源,用defer确保即使执行出错也能正常释放。
  • 循环结束后要检查rows.Err(),捕获遍历过程中可能出现的隐性错误。

内容的提问来源于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.24 12:48:22