luc*_*iet 29 database reflection go
我想用反射来调用Rows.Scan()函数.然而,它需要可变数量的指针,但我是Golang的新手,并没有很多源代码示例.我需要使用反射,因为我计划使用Query调用中的值填充切片.所以基本上使用rows.Columns()获得该行的长度,然后make()切片[]interface{}来填充数据点通常会使用传递到指针填充Scan()功能.
基本上像这样的代码:
col := rows.Columns()
vals := make([]interface{}, len(cols))
rows.Scan(&vals)
Run Code Online (Sandbox Code Playgroud)
任何人都有一个调用可变参数函数的例子,它使用我可以看一下的反射来获取指针?
编辑:示例代码似乎没有做我想要的.
package main
import (
_ "github.com/lib/pq"
"database/sql"
"fmt"
)
func main() {
db, _ := sql.Open(
"postgres",
"user=postgres dbname=Go_Testing password=ssap sslmode=disable")
rows, _ := db.Query("SELECT * FROM _users;")
cols, _ := rows.Columns()
for rows.Next() {
data := make([]interface{}, len(cols))
rows.Scan(data...)
fmt.Println(data)
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
[<nil> <nil> <nil> <nil> <nil>]
[<nil> <nil> <nil> <nil> <nil>]
[<nil> <nil> <nil> <nil> <nil>]
[<nil> <nil> <nil> <nil> <nil>]
[<nil> <nil> <nil> <nil> <nil>]
[<nil> <nil> <nil> <nil> <nil>]
Run Code Online (Sandbox Code Playgroud)
luc*_*iet 50
这是我到达的解决方案.它在遍历数据之前没有得到类型,因此在拉出值之前不知道每个值的类型Scan(),但关键是真的不必事先了解类型.
诀窍是创建2个切片,一个用于值,另一个用于保持与值切片平行的指针.然后,一旦指针用于填充数据,则值数组实际上填充了数据,然后可以使用这些数据来填充其他数据结构.
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
要清醒:您还可以分配界面而不是制作切片
以下代码效果很好:
var sql = "select * from table"
rows, err := db.Query(sql)
columns, err = rows.Columns()
colNum := len(columns)
var values = make([]interface{}, colNum)
for i, _ := range values {
var ii interface{}
values[i] = &ii
}
for rows.Next() {
err := rows.Scan(values...)
for i, colName := range columns {
var raw_value = *(values[i].(*interface{}))
var raw_type = reflect.TypeOf(raw_value)
fmt.Println(colName,raw_type,raw_value)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17297 次 |
| 最近记录: |