全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-21 7 分钟 ✍️ juanwangdev

GORM 数据库错误处理

数据库层面错误如唯一约束冲突、外键约束违反等需特殊处理,本文介绍识别方法与处理策略。

数据库错误类型

数据库错误由底层驱动返回,需通过错误码或类型判断:

Go
import (
    "errors"
    "gorm.io/gorm"
    "gorm.io/driver/mysql"
)

// MySQL 错误码
const (
    ErrDupEntry         = 1062 // 唯一约束冲突
    ErrNoReferencedRow  = 1452 // 外键约束违反
    ErrRowIsReferenced  = 1451 // 被引用无法删除
)

唯一约束冲突处理

Go
import "github.com/go-sql-driver/mysql"

err := db.Create(&User{Email: "test@example.com"}).Error
if err != nil {
    var mysqlErr *mysql.MySQLError
    if errors.As(err, &mysqlErr) && mysqlErr.Number == ErrDupEntry {
        return fmt.Errorf("邮箱已存在")
    }
}

外键约束违反处理

Go
// 删除被外键引用的记录
err := db.Delete(&user).Error
if err != nil {
    var mysqlErr *mysql.MySQLError
    if errors.As(err, &mysqlErr) && mysqlErr.Number == ErrRowIsReferenced {
        return fmt.Errorf("该用户有关联订单,无法删除")
    }
}

// 插入引用不存在的外键记录
err := db.Create(&Order{UserID: 999}).Error
if errors.As(err, &mysqlErr) && mysqlErr.Number == ErrNoReferencedRow {
    return fmt.Errorf("用户不存在")
}

错误处理策略

错误类型处理策略
唯一约束冲突返回友好提示,或改为更新操作
外键违反检查关联数据是否存在
数据类型错误检查字段类型与长度
连接错误重试或切换数据源
Go
// 策略1: 冲突时改为更新
err := db.Create(&user).Error
if isDuplicateError(err) {
    db.Where("email = ?", user.Email).Updates(user)
}

// 策略2: 使用事务回滚
tx := db.Begin()
defer func() {
    if r := recover(); r != nil {
        tx.Rollback()
    }
}()

不同数据库错误码不同,PostgreSQL 使用 pq 错误码,SQLite 使用 sqlite.ErrConstraint。

要点总结

  • 数据库错误通过 errors.As 解析具体错误类型
  • 唯一约束冲突返回 1062 错误码
  • 外键约束违反分 1451(被引用)和 1452(引用不存在)
  • 根据错误类型采取重试、回滚或提示策略

文章存放路径:D:\git2\jwdev\articles\GORM\进阶\错误处理与日志\数据库错误处理.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 GORM 慢查询监控
下一篇 → GORM 日志配置与输出
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库