【问题标题】:SQL Server delete trigger - row handle referred to a deleted row or a row marked for deletionSQL Server 删除触发器 - 引用已删除行或标记为删除的行的行句柄
【发布时间】: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 中的父记录。
  • 您找到解决方案了吗?

标签: sql-server triggers


【解决方案1】:

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

【讨论】:

【解决方案2】:

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

【讨论】:

  • 表在不同的数据库中,所以没有外键。因此我们使用了触发器。
猜你喜欢
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多