Разрешить обновление столбца по триггеру, но запретить прямое обновление этого же столбца - PullRequest
0 голосов
/ 11 июня 2018

У меня есть две таблицы, в которых есть несколько столбцов:

Table1:
+----+----+----+
| A  | B  | C  |
+----+----+----+
| a1 | b1 | c1 |
| a2 | b2 | c2 |
| a3 | b3 | c3 |
+----+----+----+

Table2:
+----+----+----+----+
| E  | F  | A  | C  |
+----+----+----+----+
| e1 | f1 | a1 | c1 |
| e2 | f2 | a2 | c2 |
| e3 | f3 | a3 | c3 |
+----+----+----+----+

Вкл. Table1 У меня есть триггер, который обновляет столбец A в Table2 после его обновления в Table1.Но также у меня есть триггер на Table2, который предотвращает прямое обновление столбца A в Table2.Обновление должно быть разрешено только по первому триггеру.Проблема, с которой я сталкиваюсь, заключается в том, что второй триггер срабатывает, даже когда я обновляю Table2 через первый триггер.Есть ли способ предотвратить запуск второго триггера после обновления поверх первого триггера?

Trigger1:

AFTER UPDATE AS 
   IF UPDATE (IMEPREZIME)
BEGIN
    SET NOCOUNT ON;
    UPDATE t2
    SET A = i.A
    FROM DBO.Table2 t2
    INNER JOIN inserted i on t2.C = i.C
END

Trigger2:

AFTER UPDATE
AS 
IF UPDATE (A)
BEGIN
    SET NOCOUNT ON;
    IF UPDATE (A) and NOT EXISTS(SELECT A 
                from dbo.Table1 t1 
                where exists(select A 
                                from inserted i 
                                where t1.C= i.C ))
    BEGIN
        RAISERROR('DIRECT UPDATE OF COLUMN "A" IS FORBIDDEN', 16, -1)
        ROLLBACK TRAN
    END
END

1 Ответ

0 голосов
/ 11 июня 2018

В SQL Server 2016 и более поздних версиях можно установить значение SESSION_CONTEXT для короткого замыкания второго триггера.

AFTER UPDATE AS 
   IF UPDATE (IMEPREZIME)
BEGIN
    SET NOCOUNT ON;
    EXEC sp_set_session_context @key = N'FiredFromTrigger1', @value = 1;
    UPDATE t2
    SET A = i.A
    FROM DBO.Table2 t2
    INNER JOIN inserted i on t2.C = i.C;
    EXEC sp_set_session_context @key = N'FiredFromTrigger1', @value = NULL;
END;


AFTER UPDATE
AS 
IF UPDATE (A)
BEGIN
    SET NOCOUNT ON;
    IF NOT CAST(SESSION_CONTEXT(N'FiredFromTrigger1') AS bit) = 1 AND UPDATE (A) and NOT EXISTS(SELECT A 
                from dbo.Table1 t1 
                where exists(select A 
                                from inserted i 
                                where t1.C= i.C ))
    BEGIN
        RAISERROR('DIRECT UPDATE OF COLUMN "A" IS FORBIDDEN', 16, -1);
        ROLLBACK TRAN;
    END;
END;
...