【问题标题】:SQL Delete Statement only deleting last rowSQL Delete 语句只删除最后一行
【发布时间】:2016-06-09 23:13:13
【问题描述】:

我正在尝试使用 Azure 的 SQL 数据库进行一些批量删除,我运行如下语句:

delete from DbRoles where AccountID = 41;

人们会期望 AccountID 为 41 的所有行,但它只会从表中删除最后匹配的行。我发现无论是使用常规的“where”语句还是使用像

这样的子查询,这都是正确的
 where Id in (select Id from DbRoles where AccountID = 41)

(而Id in (41, 42, 43, ... etc) 也失败了)有人知道为什么会这样吗?

----- 编辑-----

更多信息以回答 cmets 中的一些问题: Roles 表确实有一个删除触发器(感谢@Steve Ford 的提示)我们有一个连接到 Roles 表的 Closure 表,当角色表中发生操作时,它会通过触发器进行更新。其中之一是删除触发器,其内容如下:

CREATE TRIGGER [tr_dbRole_delete]
    ON [dbo].[DbRoles]
    Instead of DELETE
    AS
    BEGIN

         declare @roleID int;

         select @roleID = Id from deleted

         --delete self closure
         delete from DbRoleClosures
         where childID = @roleID and parentID = @roleID

         --delete role
        delete from DbRoles
        where Id = @roleID

    END

我认为“Instead”声明可能是我的罪魁祸首,有人可以验证吗?

【问题讨论】:

  • 我的猜测是您的说法根本不正确,并且正在发生其他事情。该语句实际上应该只删除与 where 子句匹配的所有行。
  • 可能是其他行在其他表中有引用数据。
  • 桌上有触发器吗?
  • 感谢@SteveFord 的提示,我用有关桌上触发器的其他信息更新了问题。想法?

标签: sql azure azure-sql-database


【解决方案1】:

由于此语句,您的触发器仅删除一行:

select @roleID = Id from deleted

当您删除多行时,@roleID 将设置为 ID 之一,具体取决于 SQL Server 查询已删除表的顺序。

触发器应该是这样的:

CREATE TRIGGER [tr_dbRole_delete]
ON [dbo].[DbRoles]
Instead of DELETE
AS
BEGIN


     --delete self closure
     delete from DbRoleClosures
     where childID = parentId AND
           childID in (SELECT Id from deleted)

     --delete role
    delete from DbRoles
    where Id in (SELECT Id from deleted)

END

【讨论】:

  • 完美,谢谢@SteveFord,这正是问题所在,现在我要带着这种心态去更新我们所有的触发器了。
猜你喜欢
  • 2017-12-04
  • 2013-04-02
  • 2019-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
相关资源
最近更新 更多