Go SQL driver get interface{} 列值
Go SQL driver get interface{} column values
我正在尝试使用 go sql 驱动程序从数据库表中读取,并将值转换为 []map[string]interface{}
。列名是映射的键,值是interface{}
。我将所有列添加到一个数组中。我在 https://github.com/go-sql-driver/mysql/wiki/Examples 处使用 "RawBytes" 的代码示例作为开始的示例。
然而,在示例中 - 所有列值都转换为 string
,如下所示,
// Fetch rows
for rows.Next() {
// get RawBytes from data
err = rows.Scan(scanArgs...)
if err != nil {
panic(err.Error()) // proper error handling instead of panic in your app
}
// Now do something with the data.
// Here we just print each column as a string.
var value string
for i, col := range values {
// Here we can check if the value is nil (NULL value)
if col == nil {
value = "NULL"
} else {
value = string(col) //ATTN : converted to string here
}
fmt.Println(columns[i], ": ", value)
}
fmt.Println("-----------------------------------")
}
有没有办法将其保留为 interface{}
,这样我就可以在使用 []map[string]interface{}
中的列时进行必要的类型转换
参见 我的回答所基于的回答。使用它你可以做这样的事情:
var myMap = make(map[string]interface{})
rows, err := db.Query("SELECT * FROM myTable")
defer rows.Close()
if err != nil {
log.Fatal(err)
}
colNames, err := rows.Columns()
if err != nil {
log.Fatal(err)
}
cols := make([]interface{}, len(colNames))
colPtrs := make([]interface{}, len(colNames))
for i := 0; i < len(colNames); i++ {
colPtrs[i] = &cols[i]
}
for rows.Next() {
err = rows.Scan(colPtrs...)
if err != nil {
log.Fatal(err)
}
for i, col := range cols {
myMap[colNames[i]] = col
}
// Do something with the map
for key, val := range myMap {
fmt.Println("Key:", key, "Value Type:", reflect.TypeOf(val))
}
}
然后使用 reflect 包,您可以根据需要获取每列的类型,如末尾循环所示。
这是通用的,适用于任何 table、列数等
经过长期的努力,我找到了解决方案。检查下面将 sql.RawBytes 转换为 Int64 的函数。这可以很容易地改变以适应任何数据类型
func GetInt64ColumnValue(payload sql.RawBytes) (int64, error) {
content := reflect.ValueOf(payload).Interface().(sql.RawBytes) // convert to bytes
data := string(content) //convert to string
i, err := strconv.ParseInt(data,10,64) // convert to int or your preferred data type
if err != nil {
log.Printf("got error converting %s to int error %s ",data,err.Error())
return 0, err
}
return i, nil
}
我正在尝试使用 go sql 驱动程序从数据库表中读取,并将值转换为 []map[string]interface{}
。列名是映射的键,值是interface{}
。我将所有列添加到一个数组中。我在 https://github.com/go-sql-driver/mysql/wiki/Examples 处使用 "RawBytes" 的代码示例作为开始的示例。
然而,在示例中 - 所有列值都转换为 string
,如下所示,
// Fetch rows
for rows.Next() {
// get RawBytes from data
err = rows.Scan(scanArgs...)
if err != nil {
panic(err.Error()) // proper error handling instead of panic in your app
}
// Now do something with the data.
// Here we just print each column as a string.
var value string
for i, col := range values {
// Here we can check if the value is nil (NULL value)
if col == nil {
value = "NULL"
} else {
value = string(col) //ATTN : converted to string here
}
fmt.Println(columns[i], ": ", value)
}
fmt.Println("-----------------------------------")
}
有没有办法将其保留为 interface{}
,这样我就可以在使用 []map[string]interface{}
参见 我的回答所基于的回答。使用它你可以做这样的事情:
var myMap = make(map[string]interface{})
rows, err := db.Query("SELECT * FROM myTable")
defer rows.Close()
if err != nil {
log.Fatal(err)
}
colNames, err := rows.Columns()
if err != nil {
log.Fatal(err)
}
cols := make([]interface{}, len(colNames))
colPtrs := make([]interface{}, len(colNames))
for i := 0; i < len(colNames); i++ {
colPtrs[i] = &cols[i]
}
for rows.Next() {
err = rows.Scan(colPtrs...)
if err != nil {
log.Fatal(err)
}
for i, col := range cols {
myMap[colNames[i]] = col
}
// Do something with the map
for key, val := range myMap {
fmt.Println("Key:", key, "Value Type:", reflect.TypeOf(val))
}
}
然后使用 reflect 包,您可以根据需要获取每列的类型,如末尾循环所示。
这是通用的,适用于任何 table、列数等
经过长期的努力,我找到了解决方案。检查下面将 sql.RawBytes 转换为 Int64 的函数。这可以很容易地改变以适应任何数据类型
func GetInt64ColumnValue(payload sql.RawBytes) (int64, error) {
content := reflect.ValueOf(payload).Interface().(sql.RawBytes) // convert to bytes
data := string(content) //convert to string
i, err := strconv.ParseInt(data,10,64) // convert to int or your preferred data type
if err != nil {
log.Printf("got error converting %s to int error %s ",data,err.Error())
return 0, err
}
return i, nil
}