如何使用Golang处理SQL查询错误_判断查询结果和执行异常


Go中需区分SQL查询执行失败与结果为空:Exec错误表操作失败;QueryRow.Scan遇sql.ErrNoRows表无匹配行;Query需遍历rows.Next()后检查rows.Err()。

在 Go 中处理 SQL 查询错误,关键在于区分两类问题:查询执行失败(如连接中断、语法错误)和查询成功但结果为空(如 WHERE 条件不匹配)。这两者需要不同的判断逻辑和响应方式。

区分 Exec / Query 的错误类型

Go 的 database/sql 包中,Exec 用于无返回结果的操作(INSERT/UPDATE/DELETE),QueryQueryRow 用于 SELECT。它们的错误含义不同:

  • Exec 返回的 error 表示操作未成功执行(例如主键冲突、权限不足、网络断开)
  • QueryRow.Scan() 的错误通常表示“查到了行但字段类型不匹配”,而 QueryRow.Err() 才能告诉你是否真的没查到数据
  • Query 返回 *Rows,需用 rows.Next() 遍历;若 rows.Next() 返回 falserows.Err() == nil,说明查询成功但无结果

正确判断“查不到数据”而不是“查询失败”

常见错误是把 sql.ErrNoRows 当作通用错误直接 panic 或 log,但它只适用于 QueryRow 场景。正确做法:

  • QueryRow(...).Scan(&v) 时,检查 error 是否等于 sql.ErrNoRows —— 这代表“有查询、无匹配行”
  • Query(...) 时,不要依赖 rows.Err() 判断空结果;先循环 rows.Next(),结束后再看 rows.Err() 是否非 nil
  • 示例:
      row := db.QueryRow("SELECT name FROM users WHERE id = ?", 999)
      var name string
      if err := row.Scan(&name); err != nil {
        if errors.Is(err, sql.ErrNoRows) {
          // 正常业务逻辑:用户不存在
        } else {
          // 真正的异常:比如 name 字段是 []byte 却 Scan 到 string
        }
      }

统一处理执行类错误(INSERT/UPDATE/DELETE)

ExecExecContext 的 error 是运行时异常信号,必须显式检查:

  • 数据库约束错误(如唯一键冲突)会返回具体 driver 错误,可用 errors.As 提取底层错误码(如 MySQL 的 mysql.MySQLError
  • 连接类错误(如 timeout、connection refused)通常包含在 net.OpError 或 driver 自定义错误中,适合重试或降级
  • 建议封装一个辅助函数判断常见错误类型,例如:
      func IsDuplicateKey(err error) bool {
        var mysqlErr *mysql.MySQLError
        return errors.As(err, &mysqlErr) && mysqlErr.Number == 1062
      }

避免忽略 Rows.Close()Scan 后的 Err()

资源泄漏和静默失败常源于这两个细节:

  • 所有 *Rows 必须调用 rows.Close()(可用 defer rows.Close()),否则连接不会释放
  • rows.Scan() 可能成功,但后续 rows.Next() 失败(如网络中断),所以每次循环后应检查 rows.Err()
  • 反例:
      rows, _ := db.Query("SELECT ...")
      for rows.Next() {
        var x int
        rows.Scan(&x) // ❌ 忽略 Scan 错误
      }
      // ❌ 忘记 rows.Close()
      // ❌ 没检查 rows.Err() 是否发生读取中断


# mysql  # go  # golang  # sql  # String  # if  # for  # 封装  # select  # Error  # bool  # int  # 循环  # var  # nil  # delete  # number  # database  # 数据库  # 遍历  # 为空  # 不匹配  # 适用于  # 这两个  # 不存在  # 自定义  # 你是否  # 再看  # 两类 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: 如何在 Django 中修改用户密码后保持会话不丢失  如何使用Golang实现文件追加操作_向已有文件追加数据  php8.4xdebug无法调试怎么办_php8.4xdebug配置问题解决【解答】  Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】  如何在Golang中捕获JSON序列化错误_Golangjson.Marshal错误处理示例  C++如何获取CPU核心数?(std::thread::hardware_concurrency)  如何使用Golang reflect检查方法数量_动态分析类型方法  php中::能用于接口静态方法吗_接口静态方法调用规则【操作】  php8.4如何配置ssl证书_php8.4https访问配置指南【教程】  Win11时间怎么同步到原子钟 Win11高精度时间同步设置【指南】  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  Win10系统映像怎么恢复 Win10使用系统映像还原电脑【指南】  作用域操作符会影响性能吗_php静态调用性能分析【教程】  windows如何测试网速_windows系统网络速度测试方法  Win10闹钟铃声怎么自定义 Win10闹钟自定义铃声教程【方法】  如何使用Golang实现容器健康检查_监控和自动重启  c++如何连接Redis c++ hiredis库使用教程【指南】  如何在Golang中处理通道发送接收错误_防止阻塞或panic  Win11用户账户控制怎么关_Win11关闭UAC弹窗提示【设置】  Win11怎么设置快速访问_Windows11文件资源管理器主页  Windows10系统怎么查看防火墙状态_Win10安全中心网络保护  Win10如何更改电脑休眠时间_Windows10电源和睡眠选项调整  Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】  Win10怎么创建桌面快捷方式 Win10为应用创建快捷方式【步骤】  php中::能访问全局变量吗_全局作用域与类作用域区分【操作】  如何提升Golang JSON序列化性能_Golang JSON编码效率优化方法  如何正确访问 Laravel 模型或对象的属性而非调用不存在的方法  c++ std::future和std::promise c++线程间通信【教程】  Win11怎么更改盘符_Win11磁盘管理修改驱动器号【步骤】  Win11怎么制作U盘启动盘_Win11原版系统安装盘制作【详解】  Win11怎么设置声音输出设备_Windows11音量合成器单独调节应用  php后缀怎么变mp4能播放_让php伪装mp4正常播放的技巧【技巧】  C#如何序列化对象为XML XmlSerializer用法  c++中的std::conjunction和std::disjunction是什么_c++模板元编程逻辑运算【C++17】  PHP的FastAdmin架构适合二次开发吗_特点分析【介绍】  PhpStorm怎么调试PHP代码_PhpStorm断点设置与调试启动步骤【指南】  PHP 中如何在函数内持久化修改引用变量的指向  C++中引用和指针有什么区别?(代码说明)  Win11如何开启telnet服务 Win11启用Telnet客户端【步骤】  Python与Docker容器化部署实战_镜像构建与CI/CD流程  Win11怎么设置ip地址_Windows 11手动配置网络IP教程【详解】  XML的“混合内容”是什么 怎么用DTD或XSD定义  Win11开机自检怎么关闭_跳过Win11开机磁盘扫描修复方法【技巧】  XSLT怎么生成动态的HTML属性名和标签名  Python网络异常模拟_测试说明【指导】  Mac怎么给文件夹加密_Mac创建加密磁盘映像教程【安全】  Win10怎样安装PPT模板_Win10安装PPT模板教程【步骤】  使用类变量定义字符串常量时的类型安全最佳实践  如何使用Golang优化模块引入路径_Golanggo mod tidy清理与优化方法  php打包exe怎么传递参数_命令行参数接收方法【解答】 

 2026-01-03

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.