Heim >Backend-Entwicklung >Golang >Wie verwende ich Reflection, um die variadische Datenbank-/SQL-Funktion Rows.Scan() aufzurufen?

Wie verwende ich Reflection, um die variadische Datenbank-/SQL-Funktion Rows.Scan() aufzurufen?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-05 09:56:11755Durchsuche

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

Aufrufen der Scan() Variadic-Funktion mit Reflection

Die Rows.Scan()-Funktion bietet eine praktische Möglichkeit, Daten aus einer Datenbank abzurufen Abfrage. Es verwendet jedoch eine variable Anzahl von Zeigern als Argumente, deren Integration mithilfe von Reflektion schwierig sein kann. Stellen Sie sich das folgende Szenario vor:

Sie möchten ein Segment dynamisch mit aus einer Abfrage erhaltenen Werten füllen und Rows.Scan() verwenden, um die Daten zu extrahieren. In diesem Fall müssen Sie die Anzahl der Spalten bestimmen und ein Slice zum Speichern der Werte erstellen.

Eine häufige Gefahr:
Ein Versuch, Reflektion zum Aufrufen zu verwenden Die Scan()-Funktion kann zu unerwarteten Ergebnissen führen. Dies liegt daran, dass Rows.Scan() Zeiger auf die Werte erwartet und die einfache Übergabe eines Segments von Interface{}-Werten zu Null-Referenzen führen würde.

Die Lösung:

Um Scan() erfolgreich mit Reflektion aufzurufen, wird ein Dual-Slice-Ansatz verwendet. Das erste Segment, „values“, enthält die eigentlichen Daten, während das zweite Segment, „valuesPtrs“, Zeiger auf jedes Element in „values“ enthält.

Für jede Spalte im Abfrageergebnis wird ein Zeiger in „valuesPtrs“ dem entsprechenden Element zugeordnet in Werten. Anschließend kann Rows.Scan() mit valuePtrs als Argument aufgerufen werden, wodurch Werte effektiv gefüllt werden.

Arbeitsbeispiel:

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

In diesem Beispiel Zeilen. Scan() wird mit dem Zeiger-Slice „valuesPtrs“ aufgerufen und füllt das Werte-Slice mit den abgerufenen Daten. Die Schleife gibt dann jeden Spaltennamen und den entsprechenden Wert aus.

Das obige ist der detaillierte Inhalt vonWie verwende ich Reflection, um die variadische Datenbank-/SQL-Funktion Rows.Scan() aufzurufen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn