database/sql Scan时报错

Scan方法的源码中判断了搜索字段的个数和传入字段的个数是否相等!!!

使用Scan获取查询数据时报错

sql := "select * from demo"
demo := &Demo{}
rows, err := DB.Query(sql)
if err != nil{
    log.Fatalf("query err: %v", err)
}
defer rows.Close()
for rows.Next() {
    err = rows.Scan(&demo.Id, &demo.UserId, &demo.Number,&demo.AddTime, &demo.Status)
}
if err != nil{
    log.Fatalf("rows err: %v\n", err)
}
fmt.Printf("demo : %v",&demo)

  • 执行代码后报错
2020/12/21 20:48:20 rows err: sql: expected 7 destination arguments in Scan, not 5
exit status 1
  • 查看Scan的源码时才发现,传入的参数个数必须和搜索的字段个数一致,否则就会报错,如果select *那么就必须传入所有字段。源码如下:
func (rs *Rows) Scan(dest ...interface{}) error {
    rs.closemu.RLock()

    if rs.lasterr != nil && rs.lasterr != io.EOF {
        rs.closemu.RUnlock()
        return rs.lasterr
    }
    if rs.closed {
        err := rs.lasterrOrErrLocked(errRowsClosed)
        rs.closemu.RUnlock()
        return err
    }
    rs.closemu.RUnlock()

    if rs.lastcols == nil {
        return errors.New("sql: Scan called without calling Next")
    }
    # 这里判断了搜索的字段个数和dest的个数是否相等,不想等就会报错。
    if len(dest) != len(rs.lastcols) {
        return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
    }
    for i, sv := range rs.lastcols {
        err := convertAssignRows(dest[i], sv, rs)
        if err != nil {
            return fmt.Errorf(`sql: Scan error on column index %d, name %q: %v`, i, rs.rowsi.Columns()[i], err)
        }
    }
    return nil
}

你可能感兴趣的:(database/sql Scan时报错)