php小编小新在这篇文章中将向大家介绍如何从MySQL/Go表获取行数据。MySQL是一种流行的关系型数据库管理系统,而Go是一种强大的开发语言。在开发过程中,我们经常需要从数据库中获取数据并进行处理。本文将详细介绍如何使用Go语言连接MySQL数据库,并通过查询语句从表中获取行数据。无论您是初学者还是有经验的开发者,本文都将为您提供有用的指导和示例代码。让我们开始吧!
问题内容
首先它读取代码,以便您了解它的逻辑,当运行我捕获它的存储过程时,它会为我带来一个包含我必须返回的数据的表,列的名称确实会带来它对我来说,但列的数据没有给我带来任何东西,我无法创建模型,并且存储过程的响应有 n 个列,有 n 个不同的名称,但列的不同之处在于具有 int 数据和字符串数据,我需要您从列中捕获正确的数据,因为一切正常,但列中的数据却不起作用:
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))
}
这就是它返回给我的内容,其中显示“columns”:[“idPunto”,“nombre”]该部分没问题,但包含数据的行不是我所期望的:
解决方法
将行扫描到接口{}中不会自动将 SQL 类型转换为 Go 类型。相反,使用 ColumnTypes 方法将获取每列的数据类型,允许您动态分配正确的 Go 类型。 (以下内容未经测试,仅供参考。)例如
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]
}
在您的脚本中:
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))
}
nb:您应该能够针对可能遇到的其他数据类型扩展此逻辑。
以上就是从 MySQL/Go 表获取行数据的详细内容,更多请关注编程网其它相关文章!