Golang操作MySQL查询表数据时Scan返回空值问题求助
Go操作MySQL查询返回空值排查方案
1. 结构体字段未导出,无法被反射赋值
- Go语言中只有首字母大写的结构体字段才是公开可导出的,
database/sql包依赖反射为结构体字段赋值,你定义的reason4结构体中reason字段首字母为小写,属于包私有属性,Scan方法无法访问该字段,自然无法写入查询到的值,导致始终为空。
修复方式:将字段首字母改为大写
type reason4 struct { Reason string // 首字母大写,公开可导出 }
2. 未正确使用查询对象,遗漏必要步骤和错误处理
- 你使用
db.Query()返回的是*sql.Rows对象,使用时必须先调用Next()方法移动游标到匹配行,再执行Scan操作,且全程需要捕获返回的错误,否则即使查询报错、没有匹配行你也无法感知。 - 如果仅需要查询单行结果,更推荐使用
db.QueryRow()方法,使用逻辑更简洁。
3. 查询条件无匹配数据
你的查询语句是SELECT reason FROM misc WHERE reason=?,传入的参数是字符串"1",需要确认两点:
- 数据库中
misc表的reason字段类型是否为字符串类型,如果是数值类型,传入字符串"1"会导致类型不匹配,无法匹配到记录 - 表中确实存在
reason值为"1"的记录,无匹配记录的情况下Scan也不会写入任何值
修复后代码示例
单行查询推荐写法
type reason4 struct { Reason string } query := "SELECT reason FROM misc WHERE reason=?" var misc reason4 err := db.QueryRow(query, "1").Scan(&misc.Reason) if err != nil { // 没有匹配行时会返回sql.ErrNoRows,可根据需求做对应处理 log.Fatalf("查询失败: %v", err) } fmt.Println(misc.Reason)
若坚持使用db.Query的正确写法
type reason4 struct { Reason string } query := "SELECT reason FROM misc WHERE reason=?" var misc reason4 row1, err := db.Query(query, "1") if err != nil { log.Fatalf("执行查询失败: %v", err) } defer row1.Close() // 必须手动关闭Rows避免数据库连接泄漏 if row1.Next() { // 先调用Next移动游标到第一行 err = row1.Scan(&misc.Reason) if err != nil { log.Fatalf("读取行数据失败: %v", err) } } else { log.Println("没有匹配的记录") } fmt.Println(misc.Reason)
内容的提问来源于stack exchange,提问作者MortySU
相关产品推荐
相关产品推荐

