Sql 我的触发器中使用软删除覆盖删除的漏洞在哪里?

Sql 我的触发器中使用软删除覆盖删除的漏洞在哪里?,sql,sql-server,tsql,database-design,Sql,Sql Server,Tsql,Database Design,我创建了一个触发器 CREATE TRIGGER [CantDeleteStuff] ON [dbo].[Stuff] INSTEAD OF DELETE AS BEGIN ROLLBACK UPDATE [dbo].[Stuff] SET [Deleted]=1 FROM DELETED WHERE [dbo].[Stuff].[Id] = DELETED.[Id] END GO 我认为它的意图是明确的。但是当我试图删除一行时,我得到了错误 事务在触发器中结束。批处理已中止 如

我创建了一个触发器

CREATE TRIGGER [CantDeleteStuff] ON [dbo].[Stuff]
INSTEAD OF DELETE 
AS
BEGIN
   ROLLBACK
   UPDATE [dbo].[Stuff] SET [Deleted]=1 FROM DELETED WHERE [dbo].[Stuff].[Id] = DELETED.[Id]
END
GO
我认为它的意图是明确的。但是当我试图删除一行时,我得到了错误

事务在触发器中结束。批处理已中止


如何修复?

代替删除将用触发代码替换删除

根据Technet,触发器中的回滚是问题所在。你可以在这里读更多

触发器的操作就像在执行触发器时存在有效的未完成事务一样。无论触发触发器的语句是隐式事务还是显式事务,都是如此

当语句开始以自动提交模式执行时,存在一个隐含的BEGIN事务,允许在遇到错误时恢复该语句生成的所有修改。此隐含事务对批处理中的其他语句没有影响,因为它在语句完成时提交或回滚。但是,当调用触发器时,此隐含事务仍然有效

执行触发器时,将启动隐式事务。如果触发器完成执行且@TRANCOUNT=0,则出现错误3609,批处理终止。如果在触发器中发出BEGIN TRANSACTION语句,它将创建嵌套事务。在这种情况下,当执行COMMIT TRANSACTION语句时,该语句将仅应用于嵌套事务。 在触发器中使用回滚事务时,请注意以下行为:

回滚当前事务中对该点所做的所有数据修改,包括触发器所做的任何修改。

触发器继续执行ROLLBACK语句之后的任何剩余语句。如果这些语句中的任何一条修改了数据,则不会回滚这些修改

触发器中的回滚将关闭并取消分配在包含触发触发器的语句的批处理中声明和打开的所有游标。这包括在触发触发器的批调用的存储过程中声明和打开的游标。触发触发器的批之前的批中声明的游标仅关闭。但是,如果出现以下情况,静态或不敏感游标将保持打开状态:

光标在提交时关闭。 静态游标是同步游标或完全填充的异步游标。 可以使用SAVE TRANSACTION语句在触发器中执行部分回滚,而不是使用ROLLBACK TRANSACTION


因此,只需删除回滚。

而不是Delete将用触发代码替换Delete

根据Technet,触发器中的回滚是问题所在。你可以在这里读更多

触发器的操作就像在执行触发器时存在有效的未完成事务一样。无论触发触发器的语句是隐式事务还是显式事务,都是如此

当语句开始以自动提交模式执行时,存在一个隐含的BEGIN事务,允许在遇到错误时恢复该语句生成的所有修改。此隐含事务对批处理中的其他语句没有影响,因为它在语句完成时提交或回滚。但是,当调用触发器时,此隐含事务仍然有效

执行触发器时,将启动隐式事务。如果触发器完成执行且@TRANCOUNT=0,则出现错误3609,批处理终止。如果在触发器中发出BEGIN TRANSACTION语句,它将创建嵌套事务。在这种情况下,当执行COMMIT TRANSACTION语句时,该语句将仅应用于嵌套事务。 在触发器中使用回滚事务时,请注意以下行为:

回滚当前事务中对该点所做的所有数据修改,包括触发器所做的任何修改。

触发器继续执行ROLLBACK语句之后的任何剩余语句。如果这些语句中的任何一条修改了数据,则不会回滚这些修改

触发器中的回滚将关闭并取消分配在包含触发触发器的语句的批处理中声明和打开的所有游标。这包括在触发触发器的批调用的存储过程中声明和打开的游标。触发触发器的批之前的批中声明的游标仅关闭。但是,如果出现以下情况,静态或不敏感游标将保持打开状态:

光标在提交时关闭。 静态游标是同步游标或完全填充的异步游标。 可以使用SAVE TRANSACTION语句在触发器中执行部分回滚,而不是使用ROLLBACK TRANSACTION


因此,只需删除回滚。

只需删除Rollback语句,就可以了。请记住,您的instead of将触发而不是delete。这意味着实际上不会发生删除操作。只要删除rollback语句,就可以了。请记住,您的instead of将触发而不是delete。这意味着实际上不会发生删除。