Использование триггера для блокировки определенных строк на основе условия - PullRequest
0 голосов
/ 20 февраля 2012

Скажем, например, у кого-то есть таблица с определенными строками, как можно предотвратить обновление определенных строк на основе условия, равного true, но разрешить обновление зафиксировать на всех строках, где условие ложно.

Возьмите этот пример, где я «блокирую» все строки до 04.01.2007, прерывая всю транзакцию

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tbl_TriggerTest] (
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Value] [varchar](25) NULL,
    [Date] [datetime] NULL,
 CONSTRAINT [PK_tbl_TriggerTest] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[tbl_TriggerTest] ON 

GO
INSERT [dbo].[tbl_TriggerTest] ([ID], [Value], [Date]) VALUES (1, N'12', CAST(0x0000979A00000000 AS DateTime))
GO
INSERT [dbo].[tbl_TriggerTest] ([ID], [Value], [Date]) VALUES (2, N'13', CAST(0x00009A7500000000 AS DateTime))
GO
INSERT [dbo].[tbl_TriggerTest] ([ID], [Value], [Date]) VALUES (3, N'14', CAST(0x00009BE200000000 AS DateTime))
GO
INSERT [dbo].[tbl_TriggerTest] ([ID], [Value], [Date]) VALUES (4, N'4', CAST(0x00009D4F00000000 AS DateTime))
GO
SET IDENTITY_INSERT [dbo].[tbl_TriggerTest] OFF
GO
CREATE TRIGGER [dbo].[LockOldWelshRows] ON [dbo].[tbl_TriggerTest]
    FOR UPDATE
AS
    BEGIN
        DECLARE @Count INT
        SELECT  @Count = COUNT([ID])
        FROM    INSERTED
        WHERE   [Date] < CONVERT(DATETIME, '01/04/2007 00:00:00', 103)

        IF @Count > 0 
            BEGIN
                RAISERROR('Rows prior to 01/04/2007 are locked',16,1) 
                ROLLBACK TRANSACTION
                RETURN ;
            END
    END

GO

Если нужно было выполнить следующее:

UPDATE [tbl_TriggerTest] SET [Value] = [Value] + 'M'

Транзакциязавершится с ошибкой:

Msg 50000, Level 16, State 1, Procedure LockOldWelshRows, Line 12
Rows prior to 01/04/2007 are locked
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.

Есть ли способ изменить этот триггер, чтобы разрешить транзакцию для фиксации, но только для строк с датой> 1/4/2007

ЭтоОЧЕНЬ краткий пример (таблицы, с которыми я работаю, намного сложнее), и, если честно, я думаю, что будет чище, если вся транзакция не удалась, мне просто было любопытно, как это можно сделать.

1 Ответ

3 голосов
/ 20 февраля 2012

Вам понадобится ДО или иначе триггер INSTEAD OF и фильтр только по разрешенным строкам.

Не проверено:

CREATE TRIGGER [dbo].[LockOldWelshRows] ON [dbo].[tbl_TriggerTest]
    INSTEAD OF UPDATE
AS
    BEGIN

      UPDATE 
         T
      SET 
         T.SomeCol = I.SomeCol...
      FROM
         [dbo].[tbl_TriggerTest] T
         JOIN 
         INSERTED I ON T.keycol = I.keycol 
      WHERE
         T.[Date] >= '20070401';

    END

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