SQL Server 删除触发器 - 引用已删除行或标记为删除的行的行句柄

Posted

技术标签:

【中文标题】SQL Server 删除触发器 - 引用已删除行或标记为删除的行的行句柄【英文标题】:SQL Server delete trigger - row handle referred to a deleted row or a row marked for deletion 【发布时间】:2009-11-19 22:24:41 【问题描述】:

我在一个表上有一个删除触发器,用于从另一个数据库的表中删除条目。

CREATE TRIGGER [dbo].[Trigger_Contracts_Delete] ON [dbo].[Contracts]
AFTER DELETE NOT FOR REPLICATION
AS
  IF @@ROWCOUNT = 0 RETURN

  DELETE seconddb.dbo.second_table 
  WHERE contractId IN (SELECT d.ContractID FROM deleted d)

当我使用我的应用程序(旧版应用程序对其内部一无所知)删除记录时,我收到错误“行句柄引用了已删除的行或标记为删除的行”

但是,当我修改此触发器以在删除之前添加额外的选择语句 (SELECT d.ContractID FROM deleted d) 时。我没有收到错误消息。添加 select 语句时它起作用的原因是什么,是否通过在“deleted”上发出 select 我锁定了“deleted”表? 它正在发出一个

CREATE TRIGGER [dbo].[Trigger_Contracts_Delete] ON [dbo].[Contracts]
AFTER DELETE NOT FOR REPLICATION
AS
   IF @@ROWCOUNT = 0 RETURN

   SELECT d.ContractID FROM deleted d;

   DELETE seconddb.dbo.second_table 
   WHERE contractId IN (SELECT d.ContractID FROM deleted d)

【问题讨论】:

seconddb.dbo.secondtable 上是否有触发器。通常,当尝试在未提交事务的中间引用表中的行时,会发生此错误。只是想一想,尝试在 IN (SELECT d.ContractID FROM deleted d) 中添加一个 NOLOCK 提示 谢谢 Sparky。这里有更多细节 seconddb.dbo.second_table 有一个子表 seconddb.dbo.second_table_child 具有级联删除关系[如果 seconddb.dbo.second_table 中的父记录被删除,则 seconddb.dbo.second_table_child 中的子记录将被删除。 ]。 seconddb.dbo.second_table_child 上有一个删除触发器,用于在删除 seconddb.dbo.second_table_child 中的一行时更新 seconddb.dbo.second_table 中的父记录。 您找到解决方案了吗? 【参考方案1】:

您的表缺少主键! 添加主键,问题就会消失。

【讨论】:

我希望我当时已经发布了调查结果。现在我不记得了,也没有回头路——换工作。 我自己从来没有经历过,但根据robertoschiabel.wordpress.com/2008/10/20/…看来是可行的【参考方案2】:

如果您一直想从子表中删除记录,为什么不设置级联 delte 而不是触发器?

【讨论】:

表在不同的数据库中,所以没有外键。因此我们使用了触发器。

以上是关于SQL Server 删除触发器 - 引用已删除行或标记为删除的行的行句柄的主要内容,如果未能解决你的问题,请参考以下文章

删除单个表时 SQL Server 触发器

Sql Server 2005 - 插入更新触发器 - 获取更新,插入行

SQL Server - 使用表触发器记录表插入,更新,删除行数

20180927 SQL server ProcedureT-SQL创建前删除已存在存储过程

如何在 SQL Server 触发器中复制插入、更新、删除的行

sql server"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 解决方案