Триггер T-SQL производит изменение перед вызовом другого кода - PullRequest
0 голосов
/ 27 августа 2009

У меня есть таблица, давайте назовем [MYTABLE] , с FOR INSERT, UPDATE .

Триггеру необходимо выполнить хранимую процедуру, которая выполнит некоторую работу на основе изменений, сделанных в [MYTABLE] . Я не могу переместить код хранимой процедуры в триггер.

Пока все хорошо ... поскольку триггеры выполняются после внесения изменений, хранимая процедура не нуждается в доступе к [вставлено] или [удалено ] метатаблицы.

Однако ... триггеру необходимо изменить одно дополнительное поле ( [LastModified] smalldatetime), чтобы хранимая процедура могла использовать эти данные при обработке. Это , а не , поэтому хранимая процедура может видеть, что было вставлено / обновлено ... процедура может делать ряд вещей, основываясь на других записях, которые не были включены в обновление, инициирующее ее.

Проблема в том, что если мой триггер изменится [LastModified] , это либо вообще ничего не сделает (если у меня отключены рекурсивные триггеры), либо вызовет вызов хранимая процедура дважды - один раз из-за первоначального изменения запуска и снова из-за моего изменения на [LastModified] .

Как я могу обойти это так (а) [LastModified] обновляется с каждым изменением и (б) хранимая процедура вызывается только после она имеет доступ к новому значение [LastModified] ?

У меня есть две идеи, о которых я думаю, но они пахнут забавно, так что я бы лучше посмотрел, есть ли более простое решение.

Edit:

Хорошо, вот решения, которые у меня есть, может быть, это поможет обсуждению:

1. Используйте два триггера. Один, триггер «INSTEAD OF», будет обрабатывать пользовательское обновление записи и будет изменять LastModified, но будет ВЕРНУТЬСЯ быстро, если обновление наступит с SP (может расскажите на основе каких столбцов были изменены). Другой будет триггер "AFTER", который будет вызывать EXEC. Этот триггер получает обновления со столбцом LastModified , уже примененным триггером INSTEAD OF. По крайней мере, я надеюсь, что так оно и будет.

2. Переместите ModifiedDate в другую таблицу. Таким образом, у меня может быть один триггер AFTER INSERT / UPDATE, который только , если пользователь инициирует INSERT / UPDATE, добавляет запись аудита в другую таблицу и вызывает SP. SP затем изменяет другие записи, что вызывает повторный запуск триггера, но он быстро распознает ситуацию и ВОЗВРАЩАЕТСЯ, не выполняя больше работы.

Недостаток первого решения состоит в том, что мне нужно поддерживать список столбцов в триггере, чтобы обновление INSTEAD OF фактически выполняло предназначенную работу (так как я добавляю столбец в список, ModifiedDate, я не могу просто INSERT INTO tbl FROM вставлено, я должен указать столбцы).

Ответы [ 2 ]

3 голосов
/ 27 августа 2009

Вы пробовали инструкцию IF UPDATE (LastModified)?

CREATE TRIGGER XYZ ON MYTABLE 
FOR INSERT, UPDATE 
AS 
BEGIN 
IF UPDATE(LastModified) 
  RETURN 
ELSE 
  BEGIN
    UPDATE MYTABLE SET LastModified = GETDATE() 
    FROM MYTABLE INNER JOIN INSERTED ON MYTABLE.ID = INSERTED.ID
    EXEC TheStoreProc
  END
END;
0 голосов
/ 27 августа 2009

Я не уверен, что понимаю поток, который вы описываете. Это:

  1. Запись обновлена ​​
  2. Обновление запуска триггера называется
  3. триггер обновления поля LastModified
  4. триггер вызывает другой процесс

это должно работать нормально, если «другой процесс» не обновляет ту же таблицу, который снова нажал на курок.

Если "другой процесс" обновляет таблицу снова, вы можете переместить эти обновления в триггер до вызова «другого процесса».

Это какая-то помощь?

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