sqlx.QueryRow() 查不到数据返回 sql.ErrNoRows,需用 errors.Is(err, sql.ErrNoRows) 显式判断;其他错误(如连接失败、语法错误)应单独处理,不可一概而论。

sqlx.QueryRow() 返回 sql.ErrNoRows 怎么安全处理?
sqlx.QueryRow() 查不到数据时不会 panic,而是返回 sql.ErrNoRows —— 这是 Go 常见的“预期错误”,不是 bug。很多人直接忽略 err 或用 if err != nil 一锅端,结果把数据库连接失败、语法错误和“没查到”混为一谈。
- 用
errors.Is(err, sql.ErrNoRows)显式判断是否只是“无结果”,其他 err 要单独处理(比如记录日志、返回 HTTP 404 或 500) - 别在 defer 里对
*sqlx.Row调用Scan():它只执行一次,重复调用会 panic - 如果业务上“查不到 = 合法状态”,建议用指针接收,配合零值默认逻辑,例如:
var name string,然后if name == nil { / 未找到 */ }
struct 字段怎么和 SQL 列名正确映射?
sqlx 默认按字段名(非 tag)匹配列名,但 Go 字段大写、SQL 列常小写下划线,不配 tag 就会扫不到。
- 必须加
dbtag,例如:type User struct { ID intdb:"id"Name stringdb:"user_name"} - tag 值区分大小写,要和 SELECT 出来的列名完全一致(哪怕数据库是 case-insensitive,
sqlx解析时不忽略大小写) - 不要混用
json和dbtag:虽然字段名碰巧一样,但语义不同;一个漏写就 silently 失效 - 如果用
SELECT *,务必确保 struct 字段数、顺序、tag 全部匹配,否则Scan()会报sql: expected 3 destination arguments in Scan, not 2
为什么 sqlx.Select() 返回空 slice 却不报错?
sqlx.Select() 查不到数据时返回 []T{}(长度为 0 的切片),err 是 nil —— 这是设计使然,不是异常。新手常误以为“没报错=有数据”,结果后续遍历时逻辑跳过。
- 检查结果前先看
len(users),别只依赖 err - 如果业务要求“至少一条”,需要手动校验:
if len(users) == 0 { return fmt.Errorf("no users found") } - 注意:空 slice 和
nilslice 都能被json.Marshal正确序列化,但== nil判断对空 slice 返回 false,容易引发空指针联想错误
事务里用 sqlx.NamedExec() 报 driver: bad connection?
在 *sqlx.Tx 上用命名参数执行时出这个错,大概率不是连接断了,而是参数 map 里键名和 SQL 中的 :name 不匹配,或者传了 nil 值但字段不允许 NULL。
- 确保 SQL 中每个
:xxx在参数 map 中都有对应 key,且 key 是字符串字面量(不能是变量拼接后忘记引号) - 用
map[string]interface{}传参时,避免直接传 struct:sqlx 不自动展开 struct 字段,除非你用sqlx.In或显式转 map - 如果事务中混合了
QueryRow()和NamedExec(),注意前者不支持命名参数,必须用?占位符,否则会解析失败并静默丢弃参数
字段 tag 写错、参数 map 键名不一致、误把 QueryRow 当成支持命名参数——这三个地方,改起来就几秒钟,但卡住的时间往往最长。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











