透過反射呼叫Scan() 變數函數
Rows.Scan() 函數提供了一種從資料庫檢索資料的便捷方法詢問。然而,它使用可變數量的指標作為其參數,這對於使用反射來合併可能具有挑戰性。 考慮以下場景:
您希望使用從查詢獲得的值動態填充切片並利用 Rows.Scan() 提取資料。在這種情況下,您需要確定列數並建立一個切片來儲存值。
常見陷阱:
嘗試使用反射來呼叫Scan() 函數可能會導致意外結果。這是因為 Rows.Scan() 需要指向值的指針,並且簡單地傳遞一個 interface{} 值的切片將導致零引用。
解:
為了透過反射成功呼叫 Scan(),採用了雙切片方法。第一個切片values保存實際數據,第二個切片valuesPtrs包含指向values中每個元素的指標。
對於查詢結果中的每一列,valuesPtrs中的指標會對應到對應的元素在價值觀中。隨後,可以使用valuesPtrs作為參數來呼叫Rows.Scan(),從而有效地填入值。
工作範例:
package main import ( "fmt" _ "github.com/lib/pq" "database/sql" ) func main() { db, _ := sql.Open( "postgres", "user=postgres dbname=go_testing password=pass sslmode=disable") rows, _ := db.Query("SELECT * FROM _user;") columns, _ := rows.Columns() count := len(columns) values := make([]interface{}, count) valuesPtrs := make([]interface{}, count) for rows.Next() { for i := range columns { valuesPtrs[i] = &values[i] } rows.Scan(valuesPtrs...) for i, col := range columns { val := values[i] b, ok := val.([]byte) var v interface{} if (ok) { v = string(b) } else { v = val } fmt.Println(col, v) } } }
在此範例中,rows.Scan()。 Scan() 使用指標切片 valuePtrs 調用,以檢索到的資料填入值切片。然後循環列印每個列名稱及其對應的值。
以上是如何使用反射呼叫資料庫/SQL Rows.Scan() 可變參數函數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!