После обновления Триггеры и пакетные обновления - PullRequest
2 голосов
/ 16 ноября 2010

У меня есть следующий триггер, чтобы избежать обновления определенного столбца.

ALTER TRIGGER [dbo].[MyTrigger] 
   ON  [dbo].[MyTable] 
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    IF UPDATE(SomeID)
    BEGIN
        DECLARE @id INT,
                @newSomeID INT,
                @currentSomeID INT

        SELECT @id = ID, @newSomeID = SomeID
        FROM inserted

        SELECT @currentSomeID = SomeID
        FROM deleted
        WHERE ID = @id

        IF (@newSomeID <> @currentSomeID)
        BEGIN
            RAISERROR ('cannot change SomeID (source = [MyTrigger])', 16, 1)
            ROLLBACK TRAN
        END

        RETURN

    END

END

Так как я выбираю из вставленных и удаленных, будет ли это работать, если кто-то обновит таблицу, используя предложение where, которое инкапсулирует несколько строк? Другими словами, возможно ли, чтобы вставленная и удаленная таблица содержала более одной строки в области действия моего триггера?

Спасибо ...

Ответы [ 2 ]

4 голосов
/ 16 ноября 2010

почему бы не использовать вместо триггера обновления, а просто присоединиться к INSERTED и вставить все столбцы, кроме того, который вы не хотите обновлять? Ваш подход не учитывает, что один оператор UPDATE может повлиять на несколько строк.

попробуйте что-то вроде этого:

ALTER TRIGGER [dbo].[MyTrigger] 
   ON  [dbo].[MyTable] 
   INSTEAD OF UPDATE
AS 
BEGIN

    UPDATE m
        SET col1=INSERTED.col1
           ,col2=INSERTED.col2
           ,col4=INSERTED.col4
        FROM [dbo].[MyTable]      m
            INNER JOIN INSERTED   i ON m.PK=i.PK
END

Вы также можете попробовать что-то вроде этого:

ALTER TRIGGER [dbo].[MyTrigger] 
   ON  [dbo].[MyTable] 
   AFTER UPDATE
AS 
BEGIN
    IF EXISTS(SELECT 1 FROM INSERTED i INNER JOIN DELETED d ON i.PK=d.PK WHERE i.SomeID!=d.SomeID OR (i.SomeID IS NULL AND d.SomeID IS NOT NULL) OR (d.SomeID IS NULL AND i.SomeID IS NOT NULL))
    BEGIN
        RAISERROR ('cannot change SomeID (source = [MyTrigger])', 16, 1)
        ROLLBACK TRAN
        RETURN
    END
END

Это будет работать для обновлений нескольких строк. Кроме того, если «SomeID» НЕ равен NULL, вы можете удалить два условия OR в IF EXISTS

0 голосов
/ 24 августа 2015

Вам нужно определить курсор в триггере и получить все затронутые записи в курсоре, а затем обработать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...