首頁 > 後端開發 > Golang > 如何使用反射呼叫資料庫/SQL Rows.Scan() 可變參數函數?

如何使用反射呼叫資料庫/SQL Rows.Scan() 可變參數函數?

Mary-Kate Olsen
發布: 2024-12-05 09:56:11
原創
756 人瀏覽過

How to Use Reflection to Call the Database/SQL Rows.Scan() Variadic Function?

透過反射呼叫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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板