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
    })
}

这些方法避免了手动逐个删除的冗余代码,提供了可重用的解决方案。

回到顶部