触发器 - 是否有必要 BEGIN / COMMIT TRAN

Ole*_* Sh 3 sql-server triggers sql-server-2014 azure-sql-database

我想像这样创建 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
Run Code Online (Sandbox Code Playgroud)

因此,我可以确定,这些操作是一个原子操作。但这有意义还是 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
Run Code Online (Sandbox Code Playgroud)

所以,触发DeleteSecurityLevel就是删除Company并调用DeleteCompany触发器。如果每个触发器都有 BEGIN/COMMIT TRAM ,那么它将在一个事务中?如果每个触发器都没有呢?

附言。我无法设置“CASCADE DELETE”,因为数据库有一些类似的关系:

在此输入图像描述

因此,尝试设置 CASCADE DELETE 会抛出如下错误:

在表“Persons”上引入 FOREIGN KEY 约束“FK_Persons_Areas”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束或索引。请参阅以前的错误。

Dan*_*man 5

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