I have a table t
containing a lot of columns, and my sql is like this: select * from t
. Now I only want to scan one column or two from the wide returned row set. However, the sql.Scan accepts dest ...interface{}
as arguments. Does it mean I have to scan everything and use only the column I needed?
I know I could change the sql from select *
to select my_favorite_rows
, however, in this case, I have no way to change the sql.
Advertisement
Answer
You can make use of Rows.Columns, e.g.
package main import ( "database/sql" "fmt" "github.com/lib/pq" ) type Vehicle struct { Id int Name string Wheels int } // VehicleCol returns a reference for a column of a Vehicle func VehicleCol(colname string, vh *Vehicle) interface{} { switch colname { case "id": return &vh.Id case "name": return &vh.Name case "wheels": return &vh.Wheels default: panic("unknown column " + colname) } } func panicOnErr(err error) { if err != nil { panic(err.Error()) } } func main() { conn, err := pq.ParseURL(`postgres://docker:docker@172.17.0.2:5432/pgsqltest?schema=public`) panicOnErr(err) var db *sql.DB db, err = sql.Open("postgres", conn) panicOnErr(err) var rows *sql.Rows rows, err = db.Query("select * from vehicle") panicOnErr(err) // get the column names from the query var columns []string columns, err = rows.Columns() panicOnErr(err) colNum := len(columns) all := []Vehicle{} for rows.Next() { vh := Vehicle{} // make references for the cols with the aid of VehicleCol cols := make([]interface{}, colNum) for i := 0; i < colNum; i++ { cols[i] = VehicleCol(columns[i], &vh) } err = rows.Scan(cols...) panicOnErr(err) all = append(all, vh) } fmt.Printf("%#vn", all) }