SQL Server 使用触发器并摆脱 ON DELETE CASCADE

标签 sql sql-server database cascade

我有 2 个表,A 和 B。

B表有一个外键指向A表的主键,B表的外键有ON DELETE CASCADE,所以当A表的一条记录被删除时,B表对应的记录也被删除。

我的要求是跟踪历史表中所有添加/更新/删除的记录。我在每个表上都有触发器将记录插入历史表(AHistories 和 BHistories 表)。

我不喜欢用ON DELETE CASCADE命令删除记录。触发器 A 在触发器 B 之后执行,因此我必须设法将 AHistory 的 ID 获取到 BHistory 记录中。

我想摆脱 ON DELETE CASCADE 并在触发器 A 中对 B 的记录执行删除,然后将删除的 B 记录插入 BHistories 中。

为了证明这个想法,我简化了案例,但是我还有几个表有一个外键指向表 A 中的主键。就个人而言,我希望我能指定顺序和我做什么关于删除级联。

这种方法有问题吗?任何意见表示赞赏。

最佳答案

尽管触发器很糟糕,但有时它们是实现复杂业务需求的唯一方法。在下面的示例中,我将执行如下操作 PK_ID 引用 Primary Key Column

CREATE TRIGGER tr_Table_A_InsteadOfDelete
ON dbo.TableA
INSTEAD OF DELETE
AS
BEGIN
  SET NOCOUNT ON;

BEGIN TRANSACTION;

    -- Insert into History Table from TableB

    INSERT INTO TABLE_B_History
    SELECT B.*
    FROM TableB B INNER JOIN deleted d
    ON B.PK_ID = d.PK_ID

    -- Delete rows from TableB

      DELETE FROM TableB
        WHERE EXISTS (SELECT 1 
                      FROM deleted 
                      WHERE PK_ID = TableB.PK_ID) 

    -- Insert into History Table from TableA

    INSERT INTO TABLE_A_History
    SELECT A.*
    FROM TableA A INNER JOIN deleted d
    ON A.PK_ID = d.PK_ID

    -- Delete rows from TableA

      DELETE FROM TableA
        WHERE EXISTS (SELECT 1 
                      FROM deleted 
                      WHERE PK_ID = TableA.PK_ID) 

COMMIT TRANSACTION;

END

关于SQL Server 使用触发器并摆脱 ON DELETE CASCADE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25221925/

相关文章:

sql - XSD、XML 到 SQL 导入出现问题 - 此位置不允许文本节点

ruby - 使用 Rails 3 从现有表生成模型

SQL QUERY 选择特定老板手下的员工

sql - 获取列的最大值和id

sql-server - 仅当使用列列表且 IDENTITY_INSERT 为 ON SQL Server 时,才能指定表中标识列的显式值

2个表的SQL主键

mysql - 合并/组合两个数据库表中的字段

MySQL DAYOFMONTH() 不工作

sql - EXEC sp_executesql 与 INSERT INTO :( 一起使用时非常慢

c# - 如何在 Entity Framework 中获取 SQL Server 序列的下一个值?