- 
				
				慕尼黑8549860 由于您事先不知道结构,您可以将行作为空接口的二维切片返回。但是,要使行扫描起作用,您需要将值预分配给适当的类型,为此您可以使用ColumnTypes方法和reflect包。请记住,并非每个驱动程序都提供对列类型的访问,因此请确保您使用的驱动程序提供。rows, err := db.Query("select * from foobar")if err != nil {    return err}defer rows.Close()// get column type infocolumnTypes, err := rows.ColumnTypes()if err != nil {    return err}// used for allocation & dereferencingrowValues := make([]reflect.Value, len(columnTypes))for i := 0; i < len(columnTypes); i++ {    // allocate reflect.Value representing a **T value    rowValues[i] = reflect.New(reflect.PtrTo(columnTypes[i].ScanType()))}resultList := [][]interface{}{}for rows.Next() {    // initially will hold pointers for Scan, after scanning the    // pointers will be dereferenced so that the slice holds actual values    rowResult := make([]interface{}, len(columnTypes))    for i := 0; i < len(columnTypes); i++ {        // get the **T value from the reflect.Value        rowResult[i] = rowValues[i].Interface()    }    // scan each column value into the corresponding **T value    if err := rows.Scan(rowResult...); err != nil {        return err    }    // dereference pointers    for i := 0; i < len(rowValues); i++ {        // first pointer deref to get reflect.Value representing a *T value,        // if rv.IsNil it means column value was NULL        if rv := rowValues[i].Elem(); rv.IsNil() {            rowResult[i] = nil        } else {            // second deref to get reflect.Value representing the T value            // and call Interface to get T value from the reflect.Value            rowResult[i] = rv.Elem().Interface()        }    }    resultList = append(resultList, rowResult)}if err := rows.Err(); err != nil {    return err}fmt.Println(resultList)分享编辑跟随由于您事先不知道结构,您可以将行作为空接口的二维切片返回。但是,要使行扫描起作用,您需要将值预分配给适当的类型,为此您可以使用ColumnTypes方法和reflect包。请记住,并非每个驱动程序都提供对列类型的访问,因此请确保您使用的驱动程序提供。rows, err := db.Query("select * from foobar")if err != nil {    return err}defer rows.Close()// get column type infocolumnTypes, err := rows.ColumnTypes()if err != nil {    return err}// used for allocation & dereferencingrowValues := make([]reflect.Value, len(columnTypes))for i := 0; i < len(columnTypes); i++ {    // allocate reflect.Value representing a **T value    rowValues[i] = reflect.New(reflect.PtrTo(columnTypes[i].ScanType()))}resultList := [][]interface{}{}for rows.Next() {    // initially will hold pointers for Scan, after scanning the    // pointers will be dereferenced so that the slice holds actual values    rowResult := make([]interface{}, len(columnTypes))    for i := 0; i < len(columnTypes); i++ {        // get the **T value from the reflect.Value        rowResult[i] = rowValues[i].Interface()    }    // scan each column value into the corresponding **T value    if err := rows.Scan(rowResult...); err != nil {        return err    }    // dereference pointers    for i := 0; i < len(rowValues); i++ {        // first pointer deref to get reflect.Value representing a *T value,        // if rv.IsNil it means column value was NULL        if rv := rowValues[i].Elem(); rv.IsNil() {            rowResult[i] = nil        } else {            // second deref to get reflect.Value representing the T value            // and call Interface to get T value from the reflect.Value            rowResult[i] = rv.Elem().Interface()        }    }    resultList = append(resultList, rowResult)}if err := rows.Err(); err != nil {    return err}fmt.Println(resultList) 
- 
				
				慕斯709654 此函数在不知道列类型和计数的情况下打印查询结果。这是不使用包的先前答案的变体。reflectfunc printQueryResult(db *sql.DB, query string) error {    rows, err := db.Query(query)    if err != nil {        return fmt.Errorf("canot run query %s: %w", query, err)    }    defer rows.Close()    cols, _ := rows.Columns()    row := make([]interface{}, len(cols))    rowPtr := make([]interface{}, len(cols))    for i := range row {        rowPtr[i] = &row[i]    }    fmt.Println(cols)    for rows.Next() {        err = rows.Scan(rowPtr...)        if err != nil {            fmt.Println("cannot scan row:", err)        }        fmt.Println(row...)    }    return rows.Err()}诀窍是rows.Scan可以将值扫描到*interface{},但您必须将其包装起来interface{}才能将其传递给Scanusing ...。 
- 
				
				小怪兽爱吃肉 此函数在不知道列类型和计数的情况下打印查询结果。这是不使用包的先前答案的变体。reflectfunc printQueryResult(db *sql.DB, query string) error {    rows, err := db.Query(query)    if err != nil {        return fmt.Errorf("canot run query %s: %w", query, err)    }    defer rows.Close()    cols, _ := rows.Columns()    row := make([]interface{}, len(cols))    rowPtr := make([]interface{}, len(cols))    for i := range row {        rowPtr[i] = &row[i]    }    fmt.Println(cols)    for rows.Next() {        err = rows.Scan(rowPtr...)        if err != nil {            fmt.Println("cannot scan row:", err)        }        fmt.Println(row...)    }    return rows.Err()}诀窍是rows.Scan可以将值扫描到*interface{},但您必须将其包装起来interface{}才能将其传递给Scanusing ...。