How to call the Scan variadic function using reflection

后端 未结 4 1287
暖寄归人
暖寄归人 2020-12-23 01:42

I\'m looking to call the Rows.Scan() function using reflection. However it takes a variable number of pointers, but there are not a lot of source examples. I need to use r

4条回答
  •  梦毁少年i
    2020-12-23 02:16

    Here's the solution that I've arrived at. It doesn't get the Types before traversing the data, and so doesn't know before hand the type of each value before pulling the values out through Scan(), but the point really is to not have to know the types before hand.

    The trick was to create 2 slices, one for the values, and one that holds pointers in parallel to the values slice. Then once the pointers are used to fill data, the values array is actually filled with the data, which can then be used to populate other data structures.

    package main
    
    import (
        "fmt"
        _ "github.com/lib/pq"
        "database/sql"
    )
    
    func main() {
        db, _ := sql.Open(
            "postgres",
            "user=postgres dbname=go_testing password=pass sslmode=disable")
    
        rows, _ := db.Query("SELECT * FROM _user;")
    
        columns, _ := rows.Columns()
        count := len(columns)
        values := make([]interface{}, count)
        valuePtrs := make([]interface{}, count)
    
        for rows.Next() {
            for i := range columns {
                valuePtrs[i] = &values[i]
            }
    
            rows.Scan(valuePtrs...)
    
            for i, col := range columns {
                val := values[i]
    
                b, ok := val.([]byte)
                var v interface{}
                if (ok) {
                    v = string(b)
                } else {
                    v = val
                }
    
                fmt.Println(col, v)
            }
        }
    }
    

提交回复
热议问题