2016-02-24 35 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