SQL触发器从多个表中删除

时间:2011-09-22 08:55:06

标签: tsql triggers

我有2个表之间有关系。表一是持有groupid的组。表2保持着两组之间的关系。

table 1 
GroupId, Name, Description, .......

table 2
MasterGroupId, SubGroupId, sequenceNumber

当从表1中删除某个组时,必须删除所有相关组。

这包括该组下的子组以及子组的递归。

删除前两个表中数据的示例

表Tbl_TemplateListGroup

GroupId |Name      |Description   |TemplateListId
100 | Group 1   | NULL   | 6
101 | Group 2   | NULL   | 6
102 | Group 11  | NULL  | 6
103 | Group 12  | NULL  | 6
104 | Group 13  | NULL  | 6
105 | Group 131 | NULL  | 6
106 | Group 1311    | NULL  | 6
107 | Group111  | NULL  | 6

表Tbl_TemplateListGroupGroup

Master  | Sub     SequenceNumber
Group   | Group
Id      | Id
100 | 102   | 1
100 | 103   | 2
100 | 104   | 3
102 | 107   | 1
104 | 105   | 1
105 | 106   | 1

删除后的数据示例 表Tbl_TemplateListGroup

GroupId |Name      |Description   |TemplateListId
100 |Group 1    |           |6
101 |Group 2    |           |6
102 |Group 11   |   |6
103 |Group 12   |   |6
107 |Group111   |   |6

Tabel Tbl_TemplateListGroupGroup

Master  Sub     SequenceNumber
Group   Group
Id       Id
100 |102    |1
100 |103    |2
102 |107    |1

删除声明

delete from tbl_TemplateListGroup where GroupId = 104

触发器现在是:

CREATE TRIGGER TR_TemplateListGroupDelGroup                        
on Tbl_TemplateListGroup                                           
INSTEAD OF DELETE                                                  
AS                                                                 
  BEGIN                                                            
    SET NOCOUNT ON;                                                

    BEGIN                                                          
      SELECT GroupId INTO tmpTbl FROM Tbl_TemplateListGroup        
      WHERE GroupId in (SELECT SubGroupId FROM Tbl_TemplateListGroupGroup 
                        WHERE MasterGroupId in ( select d.GroupId from deleted d ))  

      DELETE FROM Tbl_TemplateListGroupGroup                       
      WHERE SubGroupId in ( select d.GroupId from deleted d )      

      DELETE FROM Tbl_TemplateListGroupGroup                       
      WHERE MasterGroupId in ( select d.GroupId from deleted d )   

      DELETE FROM Tbl_TemplateListGroup                            
      WHERE GroupId in ( select d.GroupId from deleted d )         

      DELETE FROM Tbl_TemplateListGroup                            
      WHERE GroupId in (select GroupId FROM tmpTbl)                

      DROP TABLE tmpTbl;                                           
    END                                                            
  END                                                              

这有两个原因无效

  1. 用户没有创建表权限,因此无法创建临时表。 (还有另一种获取数据的方法)。
  2. 我认为groupid 105的组正在限制删除,因为在我添加该项与其关系之前触发器正在工作(在sa模式下)。
  3. 现在我删除两个表并用正确的数据再次填充它们。我想在DB中解决这个问题。

1 个答案:

答案 0 :(得分:0)

不幸的是,因为涉及两个表,所以仍然需要临时表。类似的东西:

CREATE TABLE #GroupIDs (ID int)

;WITH Closure AS (
    SELECT GroupId from deleted
    UNION ALL
    SELECT SubGroupId from Tbl_TemplateListGroupGroup lgg inner join Closure c on lgg.MasterGroupId = c.GroupId
)
INSERT INTO #GroupIDs (ID) SELECT GroupID from Closure

DELETE FROM Tbl_TemplateListGroupGroup where MasterGroupID in (select ID from #GroupIDs)
DELETE FROM Tbl_TemplateListGroup where GroupID in (select ID from #GroupsIDs)

这使用Recursive Common Table Expression来计算子组表的闭包。这些可以从SQL Server 2005开始提供。