去SQL驱动程序获取interface {}列值

时间:2015-03-17 15:10:53

标签: mysql types casting go

我正在尝试使用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{}

中的列时进行必要的类型转换

2 个答案:

答案 0 :(得分:1)

请参阅this https://stackoverflow.com/questions/20271123/go-lang-sql-in-parameters回答,我的答案基于此。使用它你可以做这样的事情:

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))
    }
}

使用反射包,您可以根据需要获取每列的类型,如最后的循环所示。

这是通用的,适用于任何表格,列数等。

答案 1 :(得分:0)

经过长时间的努力,我找到了解决方案。检查以下将sql.RawBytes转换为Int64的函数。可以很容易地更改它以适合任何数据类型

  bool _handleScrollNotification(ScrollNotification notification) {
    print("extenAfter : ${_scrollController.position.extentAfter}");
    if (notification is ScrollEndNotification &&
        _scrollController.position.extentAfter == 3) {
      BlocProvider.of<TravelplaceBloc>(context)
        ..add(TravelPlaceEvent.fetchNextTravelPlaces());
    }
    return false;
  }

}