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

使用GORM出现sql: Scan error报错,目标非指针问题求助

解决GORM中sql: Scan error on column index 0, name "step": destination not a pointer错误

问题原因

你用[]interface{}作为Find方法的接收对象时,GORM无法正确将数据库行数据扫描到切片元素中。因为Find要求接收的切片元素必须是可寻址的指针类型,而空interface{}切片的元素不满足这个要求。单个map[string]interface{}能正常工作,是因为GORM可直接将单行数据映射到该map中,但它仅能接收一行结果。

解决方法

方法1:用[]map[string]interface{}接收多行结果

这是最直接的替代方案,既能接收多行数据,又无需定义结构体:

results := []map[string]interface{}{}
if err := postgres.Db.Table("states").
    Select("\"step\",\"sequence\",task_name,state,TO_CHAR(time_start,'YYYY-MM-DD HH:MM:SS') time_start,TO_CHAR(time_end,'YYYY-MM-DD HH:MM:SS') time_end").
    Where("bugreport_id=?", id).
    Order("id").
    Find(&results).Error; err != nil {
    log.Error(err)
    return
}

执行后,results中每个元素对应一行数据,键为列名,值为对应字段值。

方法2:定义结构体接收(类型更安全)

若查询字段固定,推荐定义对应结构体接收结果,获得类型安全的优势:

type StateResult struct {
    Step       int    `gorm:"column:step"`
    Sequence   int    `gorm:"column:sequence"`
    TaskName   string `gorm:"column:task_name"`
    State      string `gorm:"column:state"`
    TimeStart  string `gorm:"column:time_start"`
    TimeEnd    string `gorm:"column:time_end"`
}

// 用结构体切片接收结果
results := []StateResult{}
if err := postgres.Db.Table("states").
    Select("\"step\",\"sequence\",task_name,state,TO_CHAR(time_start,'YYYY-MM-DD HH:MM:SS') time_start,TO_CHAR(time_end,'YYYY-MM-DD HH:MM:SS') time_end").
    Where("bugreport_id=?", id).
    Order("id").
    Find(&results).Error; err != nil {
    log.Error(err)
    return
}

注意结构体字段的gorm:"column:xxx"标签需与查询返回的列名对应,如task_name对应TaskName字段。

方法3:手动初始化[]interface{}的元素(不推荐)

若一定要用[]interface{},需预先为每个元素分配指针类型对象(如*map[string]interface{}),但这种方式繁琐,实用性不如前两种:

results := []interface{}{}
// 也可预先创建指针元素,如:results := []interface{}{&map[string]interface{}{}, &map[string]interface{}{}}
if err := postgres.Db.Table("states").
    Select("\"step\",\"sequence\",task_name,state,TO_CHAR(time_start,'YYYY-MM-DD HH:MM:SS') time_start,TO_CHAR(time_end,'YYYY-MM-DD HH:MM:SS') time_end").
    Where("bugreport_id=?", id).
    Order("id").
    Find(&results).Error; err != nil {
    log.Error(err)
    return
}
// 后续需将每个元素断言为*map[string]interface{}才能使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:10:23