Golang读取MySQL数据库,数据列动态变化的处理

bkzy-wangjp · · 2223 次点击
谢谢,问题已解决。
#5
更多评论
Scan error on column index 0: destination not a pointer 是要找人中译英么? 传入的不是指针。 你需要穿个指针进去。
#1
正巧我前几天研究这个问题。 我的解法不知道很好,不过解决了我的问题。 如果有专业人士,也请大家给出更完美的方案。 主要就是用了类型查询,得到内部实际类型,然后自己去构造指针放到`Scan`前的slice里面, 再调用 `rows.Scan(arr ... )` 去获取实际数据, 最终将内部的数据再通过反射取出来。 ```go package main import ( "bytes" "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) /* mysql> desc users; +-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | username | varchar(40) | NO | | NULL | | | password | varchar(256) | NO | | NULL | | | create_time | datetime | NO | | NULL | | +-------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.01 sec) mysql> select * from users; +----+----------+----------+---------------------+ | id | username | password | create_time | +----+----------+----------+---------------------+ | 1 | aa | aa | 2018-12-01 00:00:00 | | 2 | bb | bb | 2018-12-02 00:00:00 | | 3 | cc | cc | 2018-12-03 00:00:00 | | 4 | dd | dd | 2018-12-04 00:00:00 | +----+----------+----------+---------------------+ 4 rows in set (0.00 sec) */ func withReflect() { db, err := sql.Open("mysql", "go:go@/go") if err != nil { fmt.Println("open db failed") return } rows, err := db.Query("select * from users") if err != nil { fmt.Println("query db failed") return } defer rows.Close() colTypes, err := rows.ColumnTypes() if err != nil { fmt.Println("coltypes failed") return } var data = make(map[uint32]interface{}) for rows.Next() { var id uint32 var built = make([]interface{}, 0) built = append([]interface{}{&id}) for _, ct := range colTypes[1:] { switch ct.DatabaseTypeName() { case "VARCHAR": fallthrough case "DATETIME": built = append(built, new(string)) default: var i interface{} built = append(built, &i) fmt.Printf("type name is %v\n", ct.DatabaseTypeName()) } } err = rows.Scan(built...) if err != nil { fmt.Println(err) continue } data[id] = built[1:] } for k, v := range data { ss := &bytes.Buffer{} vlist := v.([]interface{}) for _, tt := range vlist { switch realStr := tt.(type) { case *string: fmt.Fprintf(ss, "%v, ", *realStr) default: fmt.Fprintf(ss, "uknown, ") } } fmt.Printf("k = %v, v = %v\n", k, ss.String()) } return } func main() { withReflect() } ```
#2