2016-02-24 108 views
0

我使用Go服务器创建了RESTful API的一个小实现。Golang服务器:发送带有可变列数的SQL查询结果的JSON

我提取网址查询参数(我知道这是不是安全,我会尽力稍后解决这个问题,但如果你有,甚至关于这个主题的建议,他们将是有益的)。

我有表名,期望的列和一些条件保存在3个变量中。 我使用这个查询:

rows, _ := db.Query(fmt.Sprintf("SELECT %s FROM %s WHERE %s", columns, table, conditions)) 

我想查询结果返回给我的前端,作为JSON。我有可变数量的未知列,所以我不能做到“标准”的方式。 我能想到的一个解决方案是从查询结果和rows.Columns()中“手动”构建一个JSON字符串。

,但我想这样做在使用类似的可变参数的接口之类的东西更sofisticated方式。问题是,即使尝试了很多,我仍然不明白它是如何工作的。

我尝试使用下面的代码

cols, err := rows.Columns()    // Get the column names; remember to check err 
vals := make([]sql.RawBytes, len(cols)) // Allocate enough values 
ints := make([]interface{}, len(cols)) // Make a slice of []interface{} 
for i := range ints { 
    vals[i] = &ints[i] // Copy references into the slice 
} 
for rows.Next() { 
    err := rows.Scan(vals...) 
    // Now you can check each element of vals for nil-ness, 
    // and you can use type introspection and type assertions 
    // to fetch the column into a typed variable. 
} 

this tutorial,但它不工作,我得到这样的错误

cannot use &ints[i] (type *interface {}) as type sql.RawBytes in assignment

即使它会工作,我不明白它。

有没有人有这个好的解决方案?一些解释会很好。

非常感谢。

回答

1

第一个问题是在这里:

for i := range ints { vals[i] = &ints[i] // Copy references into the slice }

这是你设置这意味着是RawBytes作为指针指向接口值。

在我解释什么的意思做,我会看看我能解释的总体思路是在这里。

所以常正从SQL中去,你不得不与每列和类型(ID INT,名称字符串,...)片的响应时,那么你可以读取每个SQL记录到这个片,每一列将被映射到相同类型的值。

对于像你这样,你将有更多的品种从SQL响应,需要去处理它的情况下,你可以这样做:

for i := range ints { ints[i] = &vals[i] // Copy references into the slice }

这是什么意思是每个interface的值包含指向vals数组的指针,该数组将保存来自SQL的响应。 (在我的示例中,我使用[] []字节而不是RawBytes,因此vals中的值将是SQL中的一部分字节值。)

然后,您会怎么做:

err := rows.Scan(ints...)

由于interface可以评估任何类型,当ints阵列成为人口将接受任何值,则更新基于指针瓦尔斯阵列的位置将来自SQL的值作为RawBytes类型。

HTH