插入更新后的SQL触发器

时间:2016-03-01 14:07:17

标签: sql-server tsql triggers

此代码有什么问题。

如果我这样输入

SafePaste

或者,如果我输入

Declare tmp as CURSOR FOR
Select i.ID from Inserted
OPEN tmp 

像魅力一样,但

我有什么方法可以写这样的东西

Declare tmp as CURSOR FOR
Select i.ID from Deleted
OPEN tmp 

编辑:

if @operation <> 3

set @tmp = 'SELECT i.id FROM inserted i '

 else

 set @tmp =' SELECT i.id FROM deleted i '

 DECLARE tmpUpit CURSOR FOR 
@tmp
 OPEN tmpUpit 

我需要将值从一个表插入另一个表,具体取决于状态Inserted / updated / deleted

1 个答案:

答案 0 :(得分:1)

这是完全未经测试的,因为发布的表结构与发布的触发器代码不匹配。这应该至少证明你如何重新思考这个基于集合的逻辑而不是通过痛苦的行来排行。

CREATE TRIGGER [dbo].[Trigger212] ON [dbo].[Towns]  
FOR INSERT, UPDATE, DELETE AS
BEGIN 
    SET NOCOUNT ON;

    DECLARE @operation int
    DECLARE @Variable1 nvarchar(8) = 'Woof'
    DECLARE @Variable2 nvarchar(4) = 'Foof'

    --Capture the Operation (Inserted, Deleted Or Updated) 
    IF EXISTS(SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)
        SET @operation = 1 --Insert
    ELSE
        IF EXISTS(SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
            SET @operation = 2 --update
        ELSE
            SET @operation = 3 -- DELETE

    INSERT Requests
    (
        Field1
        , Field2
        , ID
        , TableName
        , Operation
        , TimeU
        , Status
    )
    SELECT 'Woof'
        , 'Foof'
        , i.ID
        , 'Towns'
        , @operation
        , GETDATE()
        , 0
    FROM inserted i
    LEFT JOIN Requests r on r.ID = i.ID
        AND r.Operation = 3
            OR (r.Operation = 1 and r.ID = i.ID)
        AND r.Status = 0
        AND r.TableName = 'Towns'
    WHERE r.ID IS NULL

    DELETE r
    FROM Requests r
    JOIN inserted i on i.Field1 = r.Field1
        AND i.Field2 = r.Field2
        AND i.ID = r.ID
        AND i.Operation <> @operation
    WHERE r.TableName = 'Towns'
        AND r.Status = 0   
END 

总的来说,我认为触发器应该避免,但它们有它们的位置。当触发器适当时,我通常不是做这三个操作的忠实粉丝。随着时间的推移,它变得非常混乱,因为你总是需要为不同的操作做不同的逻辑。将它们分成三个触发器使得这种可能性对于维护来说不那么痛苦。