在 golang 中处理数据库错误时,应优先使用 errors.is 判断特定错误类型。1. 当查询应返回一行数据却无结果时,需检查 err == sql.errnorows 或 errors.is(err, sql.errnorows);2. 推荐使用 errors.is 因其可穿透 error wrapper;3. 实际场景中可根据不同错误返回对应的 http 状态码;4. 避免通过 err.error() 判断错误类型以防不稳定;5. 批量查询时不触发 sql.errnorows 应改用其他方式判断是否有数据。

在 Golang 中处理数据库操作错误时,很多人一开始会直接用 if err != nil 来判断有没有出错,但其实这种方式并不够“优雅”,尤其是在需要区分不同错误类型的时候。比如,我们经常需要判断是不是因为没有查询到数据导致的错误(也就是 sql.ErrNoRows),这时候就需要更细致的错误处理方式。

下面我们就来看看,在实际开发中,怎么更准确地判断和处理像 sql.ErrNoRows 这类数据库错误。

什么时候该关心 sql.ErrNoRows?
当你使用 db.QueryRow() 或者类似的方法执行一条 SQL 查询语句,并且期望返回一行数据时,如果没有结果,Golang 的 database/sql 包就会返回一个特定的错误:sql.ErrNoRows。
立即学习“go语言免费学习笔记(深入)”;
举个例子:

var name stringerr := db.QueryRow("SELECT name FROM users WHERE id = ?", 1).Scan(&name)if err != nil { if err == sql.ErrNoRows { // 没有找到记录,可以做默认处理或返回提示 } else { // 其他错误,比如数据库连接失败、SQL语法错误等 }}
这种情况下,如果不做错误细分,就无法知道到底是真的出错了,还是只是“没查到”。所以当我们明确知道某个查询应该返回一行数据时,就应该主动去判断是否是 sql.ErrNoRows。
如何正确判断特定错误?
除了 sql.ErrNoRows,数据库操作还可能遇到其他预定义错误,比如连接超时、约束冲突等。虽然标准库并没有提供太多现成的错误变量,但在实际开发中,我们可以通过以下几种方式来识别这些错误:
常见做法包括:
直接比较 err == sql.ErrNoRows使用 errors.Is(err, sql.ErrNoRows)(Go 1.13+ 推荐)判断错误字符串是否包含特定关键词(不推荐,不稳定)
举个例子,使用 errors.Is 是更现代的方式:
if errors.Is(err, sql.ErrNoRows) { // 处理没有数据的情况}
这种方式的好处是它能穿透多个 error wrapper,比直接比较更安全。
实际场景中怎么用?
在真实的业务逻辑中,错误处理往往不只是“打印日志”或者“panic”,而是要根据不同的错误做出对应的响应。比如在 API 接口中,你可能希望:
没有数据时返回 404数据库连接异常返回 503SQL 错误返回 500
这里可以写一个通用的错误处理函数来简化流程:
func handleDBError(w http.ResponseWriter, err error) { if errors.Is(err, sql.ErrNoRows) { http.NotFound(w, r) } else if strings.Contains(err.Error(), "connection refused") { http.ServeHTTPError(w, "Database unavailable", 503) } else { http.InternalServerError(w) }}
当然,这个函数可以根据你的数据库类型进一步细化,比如使用驱动特定的错误码来判断唯一约束冲突、死锁等情况。
小细节注意点
不要用 err.Error() 去判断错误类型,容易因为错误信息变化而失效。对于批量查询(比如 Query() + Scan() 循环),sql.ErrNoRows 并不会被触发,此时应通过检查循环次数是否为零来判断是否有数据。如果你用了 ORM 工具(如 GORM),它们通常封装了错误处理逻辑,但了解底层机制仍然很重要。
基本上就这些。数据库错误处理虽然看起来简单,但如果忽略细节,很容易埋下隐患。特别是像 sql.ErrNoRows 这样的常见错误,提前做好判断会让代码更健壮、更容易维护。
以上就是Golang如何优雅处理数据库操作错误 讲解sql.ErrNoRows等特定错误判断的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1391207.html
微信扫一扫
支付宝扫一扫