You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将查询数据扫描至变量,打印User结构体为空求排查

问题分析与解决

你的代码打印出空结构体,核心原因有两个:

1. 标准库database/sql的Scan不支持直接扫描结构体

Go标准库database/sql的Scan方法仅接受单个字段的指针作为参数,无法直接将查询结果映射到结构体实例。直接传递&u会导致扫描失败,但此时错误尚未被捕获,你先打印了未赋值的初始空结构体。

2. 错误处理顺序颠倒

代码中先打印u再判断err,即便扫描过程中出现错误(比如无匹配数据、字段不匹配),你看到的依然是初始空结构体,无法通过错误信息定位问题。


解决办法

方法一:标准库逐个字段扫描

明确指定查询字段,将每个字段的指针传入Scan,确保字段顺序与查询语句完全一致:

type User struct {
    Username string `db:"username"`
    Email    string `db:"email"`
    Password string `db:"password"`
}

func SearchUserInDB(db *sql.DB, userormail string) error {
    var u User
    // 避免使用SELECT *,明确指定字段,保证与Scan参数顺序匹配
    err := db.QueryRow(`
        SELECT username, email, password
        FROM users
        WHERE username = $1`, userormail).Scan(&u.Username, &u.Email, &u.Password)
    
    // 先判断错误,再使用变量
    if err != nil {
        return err
    }
    fmt.Println(u)
    return nil
}

方法二:用ORM扩展库简化结构体扫描

若需频繁映射结构体,推荐使用sqlx这类扩展库,它支持通过结构体标签自动映射字段:

// 先安装sqlx:go get github.com/jmoiron/sqlx
import "github.com/jmoiron/sqlx"

func SearchUserInDB(db *sqlx.DB, userormail string) error {
    var u User
    err := db.QueryRowx(`
        SELECT * FROM users WHERE username = $1`, userormail).StructScan(&u)
    
    if err != nil {
        return err
    }
    fmt.Println(u)
    return nil
}

额外注意事项

  • 禁止使用SELECT *,明确指定字段可避免表结构变更导致的字段顺序错位问题。
  • 错误处理必须优先于变量使用,否则初始值会干扰调试。

内容的提问来源于stack exchange,提问作者nidstang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:55:18