GORM中如何删除所有表中具有相同ID的行?
GORM中如何删除所有表中具有相同ID的行? 我有一个包含10个表的SQLite数据库,每个表都有一个唯一的ID列。
例如,如果我想删除ID为200的记录,我希望删除分布在10个表中的10行数据。
如果不使用ON DELETE CASCADE,我该如何实现?(而且我认为在SQLite中这是不可能的)。
我目前的想法是手动逐个删除,但这样代码就会变得与数据库相关且不可重用。
1 回复
在GORM中,你可以通过以下方式实现跨表删除相同ID的记录:
package main
import (
"gorm.io/gorm"
"gorm.io/driver/sqlite"
)
type Table1 struct {
ID uint `gorm:"primaryKey"`
Name string
}
type Table2 struct {
ID uint `gorm:"primaryKey"`
Data string
}
// 定义其他8个表的结构...
func deleteByIDAcrossTables(db *gorm.DB, id uint) error {
// 使用事务确保所有删除操作原子性
return db.Transaction(func(tx *gorm.DB) error {
// 删除表1中ID为200的记录
if err := tx.Delete(&Table1{}, id).Error; err != nil {
return err
}
// 删除表2中ID为200的记录
if err := tx.Delete(&Table2{}, id).Error; err != nil {
return err
}
// 继续删除其他8个表...
// if err := tx.Delete(&Table3{}, id).Error; err != nil {
// return err
// }
// ... 重复此模式
return nil
})
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 删除ID为200的所有记录
err = deleteByIDAcrossTables(db, 200)
if err != nil {
panic(err)
}
}
更通用的实现方式:
func deleteByIDGeneric(db *gorm.DB, id uint, models ...interface{}) error {
return db.Transaction(func(tx *gorm.DB) error {
for _, model := range models {
if err := tx.Delete(model, id).Error; err != nil {
return err
}
}
return nil
})
}
// 使用示例
func main() {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
tables := []interface{}{
&Table1{},
&Table2{},
// 添加其他8个表...
}
err := deleteByIDGeneric(db, 200, tables...)
if err != nil {
panic(err)
}
}
使用反射实现完全通用的解决方案:
import (
"reflect"
"gorm.io/gorm"
)
func deleteByIDReflect(db *gorm.DB, id uint, tableNames []string) error {
return db.Transaction(func(tx *gorm.DB) error {
for _, tableName := range tableNames {
// 使用原生SQL删除
result := tx.Exec("DELETE FROM ? WHERE id = ?", tableName, id)
if result.Error != nil {
return result.Error
}
}
return nil
})
}
// 或者使用模型切片
func deleteByIDModels(db *gorm.DB, id uint, models []interface{}) error {
return db.Transaction(func(tx *gorm.DB) error {
for _, model := range models {
// 获取表名
stmt := &gorm.Statement{DB: tx}
stmt.Parse(model)
tableName := stmt.Schema.Table
// 执行删除
result := tx.Exec("DELETE FROM ? WHERE id = ?", tableName, id)
if result.Error != nil {
return result.Error
}
}
return nil
})
}
这些方法避免了手动逐个删除的冗余代码,提供了可重用的解决方案。

