英文:
Go SQL driver get interface{} column values
问题
我正在尝试使用Go SQL驱动程序从数据库表中读取数据,并将值转换为[]map[string]interface{}
。映射的键是列名,值是interface{}
类型。我将所有的列都添加到一个数组中。我正在使用https://github.com/go-sql-driver/mysql/wiki/Examples中的"RawBytes"代码示例作为起点。
然而,在该示例中,所有的列值都被转换为string
,如下所示:
// 获取行数据
for rows.Next() {
// 从数据中获取RawBytes
err = rows.Scan(scanArgs...)
if err != nil {
panic(err.Error()) // 在你的应用程序中使用适当的错误处理,而不是panic
}
// 现在对数据进行一些操作。
// 这里我们只是将每一列作为字符串打印出来。
var value string
for i, col := range values {
// 在这里我们可以检查值是否为nil(NULL值)
if col == nil {
value = "NULL"
} else {
value = string(col) // 注意:在这里转换为字符串
}
fmt.Println(columns[i], ": ", value)
}
fmt.Println("-----------------------------------")
}
有没有办法保留它作为interface{}
,这样我就可以在使用[]map[string]interface{}
中的列时进行必要的类型转换呢?
英文:
I am trying to use go sql driver to read from database tables and I am converting the values to []map[string]interface{}
. The column name is the key of the map and the values are of interface{}
. I am adding all the columns into an array. I am using the code sample for "RawBytes" at https://github.com/go-sql-driver/mysql/wiki/Examples as an example to start with.
However, in the example -all the column values are converted to string
as follows,
// 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("-----------------------------------")
}
Is there a way to retain it as interface{}
so I can do the necessary type casting while using the columns from []map[string]interface{}
答案1
得分: 3
参考这个答案,你可以像这样做:
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
}
// 使用map进行操作
for key, val := range myMap {
fmt.Println("Key:", key, "Value Type:", reflect.TypeOf(val))
}
}
使用reflect包,你可以根据需要获取每列的类型,就像最后的循环示例一样。
这是通用的方法,适用于任何表格、任意列数等情况。
<details>
<summary>英文:</summary>
See [this https://stackoverflow.com/questions/20271123/go-lang-sql-in-parameters][1] answer which my answer is based on. Using that you can do something like this:
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))
}
}
Using the reflect package you can then get the Type for each column as needed as demonstrated with the loop at the end.
This is generic and will work with any table, number of columns etc.
[1]: https://stackoverflow.com/questions/20271123/go-lang-sql-in-parameters
</details>
# 答案2
**得分**: 0
在经过长时间的努力后,我找到了解决方案。请检查下面的函数,它将sql.RawBytes转换为Int64。这可以很容易地修改以适应任何数据类型。
```go
func GetInt64ColumnValue(payload sql.RawBytes) (int64, error) {
content := reflect.ValueOf(payload).Interface().(sql.RawBytes) // 转换为字节
data := string(content) // 转换为字符串
i, err := strconv.ParseInt(data, 10, 64) // 转换为int或您首选的数据类型
if err != nil {
log.Printf("将%s转换为int时出错:%s", data, err.Error())
return 0, err
}
return i, nil
}
英文:
AFter a long struggle i found out the solution. Check belowfunction that converts sql.RawBytes to Int64. This can be easily altered to fit any data type
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论