触发 - 是必要的BEGIN / COMMIT TRAN

时间:2015-04-17 20:20:37

标签: sql-server triggers azure-sql-database sql-server-2014

我想像这样制作INSTEAD OF触发器:

CREATE TRIGGER [dbo].[DeleteCompany]
ON [dbo].[Company]
 INSTEAD OF DELETE
  AS 
  DECLARE @CompanyID int
  SELECT @CompanyID = deleted.CompanyID FROM deleted

  BEGIN TRAN
  DELETE FROM Project WHERE CompanyID = @CompanyID
  DELETE FROM CompanyPerson WHERE CompanyID = @CompanyID
  UPDATE PersonCompany SET CompanyID = null WHERE CompanyID = @CompanyID

  DELETE [Company]
     FROM DELETED D
     INNER JOIN [Company] T ON T.CompanyID = D.CompanyID
  COMMIT TRAN

所以,我可以肯定,这些行动是一个原子行动。但它有意义还是TRIGGER总是在内部执行?

此外,如果公司将被删除在另一个TRIGGER中,会发生什么:

CREATE TRIGGER [dbo].[DeleteSecurityLevel]
ON [dbo].[SecurityLevel]
 INSTEAD OF DELETE
  AS 
  DECLARE @SecurityLevelID int
  SELECT @SecurityLevelID = deleted.SecurityLevelID FROM deleted

  BEGIN TRAN
  DELETE FROM Company WHERE SecurityLevelId = @SecurityLevelID
  DELETE FROM CompanyRole WHERE SecurityLevelId = @SecurityLevelID
  ....

  DELETE SecurityLevel
     FROM DELETED D
     INNER JOIN SecurityLevel T ON T.SecurityLevelID = D.SecurityLevelID
  COMMIT TRAN

因此,触发DeleteSecurityLevel正在删除Company并调用DeleteCompany触发器。如果每个触发器都有BEGIN / COMMIT TRAM,它将在一个事务中?如果每个触发器都没有它?

PS。我无法设置" CASCADE DELETE"因为DB有类似的关系:

enter image description here

所以,尝试设置CASCADE DELETE会抛出错误:

  

介绍FOREIGN KEY约束' FK_Persons_Areas'桌子上   '人'可能会导致循环或多个级联路径。指定ON   DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY   限制。无法创建约束或索引。见前   错误。

2 个答案:

答案 0 :(得分:2)

您不需要在触发器内部显式事务,它们共享相同的事务工作空间和触发器内的批处理以及调用它的操作要么一起提交要么一起回滚

答案 1 :(得分:1)

所有DML语句都在事务中执行。触发器中的DML将使用触发触发器的语句的事务上下文,因此触发器内外的所有修改都是单个原子操作。