GORM Playground Link

https://github.com/go-gorm/playground/pull/1

Description

When I use raw sql to execute, and then use the query callback, the table name will use the name parsed from the previous sql.

func GetTableName(ctx context.Context, tx *gorm.DB, dest any) string {
    db := tx
    err := db.Statement.Parse(dest)
    if err == nil {
        return db.Statement.Schema.Table
    }
    return ""
}

type TableA struct {
        ID        uint            `json:"id" gorm:"primaryKey" redis:"id"`
        RealNum                  uint   `json:"real_num,omitempty"` 
        Status                   uint8  `json:"status,omitempty"`
    CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime" redis:"created_at"`
    UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime" redis:"-"`
}
type TableB struct {
        ID        uint            `json:"id" gorm:"primaryKey" redis:"id"`
        ApplyId               uint            `json:"apply_id"`   
    CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime" redis:"created_at"`
    UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime" redis:"-"`
}

type TableC struct {
        ID        uint            `json:"id" gorm:"primaryKey" redis:"id"`
        Name string            `json:"name"` 
    CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime" redis:"created_at"`
    UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime" redis:"-"`
}

func UpdateRealNumById(ctx context.Context, tx *gorm.DB) (int64, error) {
        sql := fmt.Sprintf(`UPDATE %s SET real_num = (SELECT COUNT(*) FROM %s WHERE status = 1 AND apply_id = 1), status = IF(real_num=num, 10, status), updated_at = ? WHERE id = 1`,
                GetTableName(ctx, tx, TableA{}),
                GetTableName(ctx, tx, TableB{}))
    db := tx.Exec(sql, time.Now().Format(global.DateMsTimeFormat))
        return db.RowsAffected, db.Error
}

ctx := context.Background()
db.Transaction(func(tx *gorm.DB) error {
      _, err := UpdateRealNumById(ctx, tx)
      if err != nil {
           return err
      }

        var cRes TableC{}
        // 这里会出现使用TableA的表名,而不是我想要的TableC表名
        // Here, the table name used is from TableA instead of the desired TableC table name.
        // 当我把这个代码块移动到UpdateRealNumById的上面,就没问题
        // When I move this code block above UpdateRealNumById, there is no issue.
    err =tx.Model(cRes).Where("name= ?", "test").Take(&cRes).Error
        if err != nil {
             return err
        }
return nil
})

Comment From: ppanphper

Gorm Using query callback after raw exec will use the table name of the previous handle 补充说明

Comment From: ppanphper

tx.Statement.Table = last table name

But when execute stmt.Parse(stmt.Model)

if stmt.Schema, err = schema.ParseWithSpecialTableName(value, stmt.DB.cacheStore, stmt.DB.NamingStrategy, specialTableName); err == nil && stmt.Table == "" { }

stmt.Table != ""

So the table name will not be reset

Comment From: github-actions[bot]

The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking