You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用DryRun模式获取GORM已执行的SQL语句?

不使用DryRun获取GORM执行SQL的实现方法

完全可以不开启DryRun模式获取已执行的SQL,推荐以下两种实现方案,均不影响SQL的正常执行,且可以捕获报错场景的SQL信息:

方案1:自定义GORM日志(推荐)

自定义日志是GORM官方推荐的全局SQL捕获方案,一次配置即可覆盖所有数据库操作

  • 实现GORM的logger.Interface接口,重写Trace方法,该方法会在每次SQL执行完成后被调用,可以直接获取到完整SQL、执行耗时、影响行数、错误信息等全量内容
  • 初始化GORM实例时将自定义日志实现注册到配置中即可

示例代码:

import (
  "context"
  "log"
  "time"
  "gorm.io/gorm/logger"
)

// CustomSQLLogger 自定义GORM日志实现
type CustomSQLLogger struct {
  logger.Interface
}

// Trace 重写Trace方法捕获SQL执行信息
func (l *CustomSQLLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
  sql, rowsAffected := fc()
  // 仅当SQL执行报错时记录日志,可根据业务需求调整逻辑
  if err != nil {
    log.Printf("SQL执行失败: 错误信息=%v 执行SQL=%s 影响行数=%d 执行耗时=%v", 
      err, sql, rowsAffected, time.Since(begin))
  }
  // 保留原有GORM日志逻辑,可根据需求决定是否保留
  l.Interface.Trace(ctx, begin, fc, err)
}

GORM初始化配置示例:

import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
  "gorm.io/gorm/logger"
)

dsn := "你的数据库连接串"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  // 注册自定义日志,可自行调整基础日志级别
  Logger: &CustomSQLLogger{
    Interface: logger.Default.LogMode(logger.Info),
  },
})

方案2:使用GORM回调捕获

如果不需要全局捕获,仅需要针对特定操作场景捕获SQL,可以使用GORM的回调机制,在对应操作执行完成后触发自定义逻辑:

// 给创建操作注册执行后回调,可同理给Update、Query、Delete等操作注册回调
err = db.Callback().Create().After("gorm:after_create").Register("log_error_sql", func(db *gorm.DB) {
  if db.Error != nil {
    // Explain方法会自动拼接参数,生成完整可执行的SQL语句
    fullSQL := db.Dialector.Explain(db.Statement.SQL.String(), db.Statement.Vars...)
    log.Printf("创建操作SQL报错: 错误=%v 完整SQL=%s", db.Error, fullSQL)
  }
})

注意事项

  • 两种方案均不会开启DryRun模式,SQL会正常提交到数据库执行
  • 若需要获取带参数的完整SQL,优先使用Dialector.Explain方法生成,避免手动拼接参数的安全问题和格式问题

内容的提问来源于stack exchange,提问作者Eduardo Mior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 01:15:00