2012-04-02 173 views
2

更新的行我有一个问题,我的更新触发SQL - 删除更新触发

ALTER TRIGGER tr_MyTable 
ON MyTable 
AFTER UPDATE 
AS 

BEGIN TRAN 
SET NOCOUNT ON; 

     If Update(column) 
     Begin 
      DELETE FROM MyTable WHERE <condition> 
     End 


     SET NOCOUNT OFF 
COMMIT TRAN 
GO 

我试图删除行(从MayTable),目前已在updatete的MyTable。但是当我运行触发器时该行不会被删除。是否无法删除当前在更新触发器内更新的行? (删除和更新在同一张桌子上)

谢谢!

编辑:

ALTER TRIGGER tr_MyTable 
ON MyTable 
AFTER UPDATE 
AS 

BEGIN TRAN 
SET NOCOUNT ON; 

     SELECT @ID = ID 
     FROM inserted 

     If Update(column) 
     Begin 
      DELETE FROM MyTable WHERE ID = @ID 
     End 


     SET NOCOUNT OFF 
COMMIT TRAN 
GO 

编辑2:

ALTER PROCEDURE sp_Update 
(
@ID INTEGER,) 
AS 

SET NOCOUNT ON 
Begin Tran 

      Update MyTable SET Column = Data where ID = @ID 

     Commit Tran 
SET NOCOUNT OFF 
GO 

此更新prosedure工作和列被更新。触发器也被触发,并且行删除(print语句)被执行,但不是删除语句。 但是,当我直接在表中更新列时,没有形成触发器,触发器触发,删除语句正常工作。我不使用回滚。

+0

您已经在SQl服务器上做出了最糟糕的触发错误,该错误是假设只有一条记录将被插入或删除表。如果你进行批量插入,这将不起作用。此代码是错误的,必须更改。 – HLGEM 2012-04-02 21:28:00

+0

此外,您应该不要使用sp_开始存储过程,因为这是系统过程使用的过程。你也不应该写一个没有try-catch块的事务,这样它可以被回滚。 – HLGEM 2012-04-02 21:29:25

回答

2

你要怎么删除?

你应该阅读你的价值从您的inserted和deleted表,如:

DELETE FROM MyTable WHERE id in (select ID from INSERTED) 
2

也许你想这样做,在INSTEAD OF触发器。如果有人试图更新该列,则可以删除该行,否则重新执行更新。这里唯一的挑战是你必须在触发器内重新编写更新语句。 (你也并不需要额外的BEGIN TRAN/COMMIT TRAN触发内。)

CREATE TRIGGER dbo.tr2_myTable 
ON dbo.MyTable 
INSTEAD OF UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    -- update the rows where the column hasn't changed 
    UPDATE s 
    SET col1 = i.col1, col2 = i.col2, ... 
    FROM dbo.MyTable AS s 
    INNER JOIN inserted AS i 
    ON s.key = i.key 
    INNER JOIN deleted AS d 
    ON i.key = d.key 
    AND i.column_that_should_not_change = d.column_that_should_not_change; 

    -- delete the rows where the column HAS changed 
    -- (note that this requirement sounds odd to me) 
    DELETE s 
    FROM dbo.MyTable AS s 
    INNER JOIN inserted AS i 
    ON s.key = i.key 
    INNER JOIN deleted AS d 
    ON i.key = d.key 
    AND i.column_that_should_not_change <> d.column_that_should_not_change; 
END 
GO 

注意,与您IF UPDATE()逻辑,这会触发实际处理多行(例如,一些地方该列已经改变,有些地方没有)。请注意,即使有人说UPDATE foo SET x = x;IF UPDATE(x)也是如此。

这假定您有一个关键列,并且column_that_should_not_change不可为空。如果该列允许NULL,那么逻辑会变得更复杂一些。

1

这是可能的。

如果你想,你可以在你的触发器中有DELETE FROM MyTable,这应该工作。您是否测试过确认触发器正在执行并且您的代码到达DELETE FROM MyTable WHERE <condition>行?

+0

是的,触发器正在执行,并且在从MyTable删除行之前,其中行被执行,所以删除行也应该执行。如Diego所述,我从插入的表中选择我的。 – Liss 2012-04-02 17:12:57

+0

然后我认为它一定是总是错误的。你为什么不向我们展示完整的DELETE行代码? – daniloquio 2012-04-02 17:16:04

+0

我已更新我的原始帖子。 – Liss 2012-04-02 18:07:13