

新闻资讯
技术学院Go中需区分SQL查询执行失败与结果为空:Exec错误表操作失败;QueryRow.Scan遇sql.ErrNoRows表无匹配行;Query需遍历rows.Next()后检查rows.Err()。
在 Go 中处理 SQL 查询错误,关键在于区分两类问题:查询执行失败(如连接中断、语法错误)和查询成功但结果为空(如 WHERE 条件不匹配)。这两者需要不同的判断逻辑和响应方式。
Go 的 database/sql 包中,Exec 用于无返回结果的操作(INSERT/UPDATE/DELETE),Query 或 QueryRow 用于 SELECT。它们的错误含义不同:
Exec 返回的 error 表示操作未成功执行(例如主键冲突、权限不足、网络断开)QueryRow.Scan() 的错误通常表示“查到了行但字段类型不匹配”,而 QueryRow.Err() 才能告诉你是否真的没查到数据Query 返回 *Rows,需用 rows.Next() 遍历;若 rows.Next() 返回 false 且 rows.Err() == nil,说明查询成功但无结果常见错误是把 sql.ErrNoRows 当作通用错误直接 panic 或 log,但它只适用于 QueryRow 场景。正确做法:
QueryRow(...).Scan(&v) 时,检查 error 是否等于 sql.ErrNoRows —— 这代表“有查询、无匹配行”Query(...) 时,不要依赖 rows.Err() 判断空结果;先循环 rows.Next(),结束后再看 rows.Err() 是否非 nil
WHERE id = ?", 999)Exec 和 ExecContext 的 error 是运行时异常信号,必须显式检查:
errors.As 提取底层错误码(如 MySQL 的 mysql.MySQLError)net.OpError 或 driver 自定义错误中,适合重试或降级资源泄漏和静默失败常源于这两个细节:
*Rows 必须调用 rows.Close()(可用 defer rows.Close()),否则连接不会释放rows.Scan() 可能成功,但后续 rows.Next() 失败(如网络中断),所以每次循环后应检查 rows.Err()