Dapatkan data baris daripada jadual MySQL/Go

WBOY
Lepaskan: 2024-02-13 22:30:09
ke hadapan
886 orang telah melayarinya

从 MySQL/Go 表获取行数据

Dalam artikel ini, editor php Xiaoxin akan memperkenalkan kepada anda cara mendapatkan data baris daripada jadual MySQL/Go. MySQL ialah sistem pengurusan pangkalan data hubungan yang popular, dan Go ialah bahasa pembangunan yang berkuasa. Semasa proses pembangunan, kita selalunya perlu mendapatkan data daripada pangkalan data dan memprosesnya. Artikel ini akan memperkenalkan secara terperinci cara menggunakan bahasa Go untuk menyambung ke pangkalan data MySQL dan mendapatkan data baris daripada jadual melalui pernyataan pertanyaan. Sama ada anda seorang pemula atau pembangun yang berpengalaman, artikel ini akan memberi anda panduan berguna dan kod contoh. Mari mulakan!

Kandungan soalan

Mula-mula ia membaca kod supaya anda memahami logiknya, apabila menjalankan prosedur tersimpan saya menangkapnya ia membawa saya jadual dengan data yang perlu saya kembalikan, nama-nama lajur membawanya kepada saya tetapi data lajur tidak membawa saya apa-apa dan saya tidak boleh mencipta model dan tindak balas prosedur tersimpan mempunyai n lajur dengan n nama yang berbeza tetapi lajur berbeza dengan mempunyai data int dan data rentetan, saya memerlukan anda untuk menangkap betulkan data dari lajur kerana semuanya berfungsi dengan baik tetapi data dalam lajur tidak berfungsi:

package controllers

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
)

type RequestData struct {
    FromData map[string]interface{} `json:"fromData"`
    Call     string                 `json:"Call"`
}

func HandleDatos(c *gin.Context) {
    var requestData RequestData

    if err := c.ShouldBindJSON(&requestData); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    fmt.Printf("Ejecutando procedimiento almacenado: CALL %s\n", requestData.Call)
    fmt.Printf("Parámetros: %v\n", requestData.FromData)

    var rows *sql.Rows
    var err error

    // Verifica si FromData contiene valores
    if len(requestData.FromData) > 0 {
        // Si hay valores en FromData, crea una consulta con parámetros
        query := "CALL " + requestData.Call + "("
        params := []interface{}{}
        for _, value := range requestData.FromData {
            query += "?, "
            params = append(params, value)
        }
        query = query[:len(query)-2] + ")"

        rows, err = db.Raw(query, params...).Rows()
    } else {
        // Si no hay valores en FromData, ejecuta el procedimiento almacenado sin parámetros
        rows, err = db.Raw("CALL " + requestData.Call).Rows()
    }

    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }
    defer rows.Close()

    // Convierte los resultados en un mapa
    result := make(map[string]interface{})
    columns, err := rows.Columns()
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    fmt.Printf("Columnas: %v\n", columns) // Punto de impresión

    data := [][]interface{}{} // Almacena los datos de filas
    for rows.Next() {
        values := make([]interface{}, len(columns))
        for i := range columns {
            values[i] = new(interface{})
        }

        if err := rows.Scan(values...); err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }

        fmt.Printf("Valores escaneados: %v\n", values) // Punto de impresión

        row := make(map[string]interface{})
        for i, col := range columns {
            val := *(values[i].(*interface{}))
            row[col] = val
        }

        fmt.Printf("Fila escaneada: %v\n", row) // Punto de impresión

        // Agrega esta fila al resultado
        data = append(data, values)
    }

    fmt.Printf("Datos finales: %v\n", data) // Punto de impresión

    if len(data) > 0 {
        result["columns"] = columns
        result["data"] = data
    } else {
        // Si no hay datos, establece un mensaje personalizado
        result["message"] = "Sin datos"
    }

    // Convierte el resultado en JSON y devuelve la respuesta
    responseJSON, err := json.Marshal(result)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, string(responseJSON))
}
Salin selepas log masuk

Inilah yang mengembalikan saya, tertera "lajur": ["idPunto", "nombre"] Bahagiannya ok, tetapi baris yang mengandungi data tidak seperti yang saya harapkan:

Penyelesaian

Imbas baris Memasuki antara muka {} tidak menukar jenis SQL kepada jenis Go secara automatik. Sebaliknya, menggunakan kaedah ColumnTypes akan mendapat jenis data setiap lajur, membolehkan anda menetapkan jenis Go yang betul secara dinamik. (Kandungan berikut belum diuji dan adalah untuk rujukan sahaja.) Contohnya

for i := range columns {
    // Use the column types to determine the appropriate scan type
    switch columnTypes[i].DatabaseTypeName() {
    case "INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT":
        scanArgs[i] = new(int64)
    default:
        scanArgs[i] = new(string)
    }

    values[i] = scanArgs[i]
}
Salin selepas log masuk

Dalam skrip anda:

package controllers

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
)

type RequestData struct {
    FromData map[string]interface{} `json:"fromData"`
    Call     string                 `json:"Call"`
}

func HandleDatos(c *gin.Context) {
    var requestData RequestData

    if err := c.ShouldBindJSON(&requestData); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    fmt.Printf("Ejecutando procedimiento almacenado: CALL %s\n", requestData.Call)
    fmt.Printf("Parámetros: %v\n", requestData.FromData)

    var rows *sql.Rows
    var err error

    // Verifica si FromData contiene valores
    if len(requestData.FromData) > 0 {
        // Si hay valores en FromData, crea una consulta con parámetros
        query := "CALL " + requestData.Call + "("
        params := []interface{}{}
        for _, value := range requestData.FromData {
            query += "?, "
            params = append(params, value)
        }
        query = query[:len(query)-2] + ")"

        rows, err = db.Raw(query, params...).Rows()
    } else {
        // Si no hay valores en FromData, ejecuta el procedimiento almacenado sin parámetros
        rows, err = db.Raw("CALL " + requestData.Call).Rows()
    }

    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }
    defer rows.Close()

    // Convierte los resultados en un mapa
    result := make(map[string]interface{})
    columns, err := rows.Columns()
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    fmt.Printf("Columnas: %v\n", columns) // Punto de impresión

    data := []map[string]interface{}{} // Almacena los datos de filas

    // Get the column types
    columnTypes, err := rows.ColumnTypes()
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    for rows.Next() {
        values := make([]interface{}, len(columns)
        scanArgs := make([]interface{}, len(columns))

        for i := range columns {
            // Use the column types to determine the appropriate scan type
            switch columnTypes[i].DatabaseTypeName() {
            case "INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT":
                scanArgs[i] = new(int64)
            default:
                scanArgs[i] = new(string)
            }

            values[i] = scanArgs[i]
        }

        if err := rows.Scan(values...); err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }

        fmt.Printf("Valores escaneados: %v\n", values) // Punto de impresión

        row := make(map[string]interface{})
        for i, col := range columns {
            // Cast the scanned values to the appropriate data types
            switch columnTypes[i].DatabaseTypeName() {
            case "INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT":
                row[col] = *(scanArgs[i].(*int64))
            default:
                row[col] = *(scanArgs[i].(*string))
            }
        }

        fmt.Printf("Fila escaneada: %v\n", row) // Punto de impresión

        // Agrega esta fila al resultado
        data = append(data, row)
    }

    fmt.Printf("Datos finales: %v\n", data) // Punto de impresión

    if len(data) > 0 {
        result["columns"] = columns
        result["data"] = data
    } else {
        // Si no hay datos, establece un mensaje personalizado
        result["message"] = "Sin datos"
    }

    // Convierte el resultado en JSON y devuelve la respuesta
    responseJSON, err := json.Marshal(result)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, string(responseJSON))
}
Salin selepas log masuk

nb: Anda sepatutnya dapat memanjangkan logik ini untuk jenis data lain yang mungkin anda hadapi.

Atas ialah kandungan terperinci Dapatkan data baris daripada jadual MySQL/Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan