Триггер, который обновляет только вставленную строку

Я пытаюсь создать простой триггер с использованием TSQL (или SQL Server 2008). Проблема в том, что мой текущий триггер обновляет всю таблицу. Это было хорошо на некоторое время, но теперь таблица имеет более 20 тыс. Строк. Поэтому я хочу, чтобы триггер обновлял только те строки, которые вставляются.

Здесь мой текущий простой триггер:

CREATE TRIGGER trig_MyPplUpdate
ON [Persons]
FOR INSERT
AS
Begin
 Update Persons
    set MyFile = NULL
    where Len(MyFile) < 60
End

Думаю, мне придется использовать либо "вставленную" таблицу, либо функцию row_number, упорядоченную первичным ключом. Любые идеи?

Ответ 1

Если вам вообще нужно использовать триггер, я бы использовал триггер INSTEAD OF, чтобы настроить значения pre-insert и избежать необходимости JOIN вернуться в базовую таблицу и затем обновить их.

CREATE TRIGGER trig_MyPplUpdate
ON [Persons]
INSTEAD OF INSERT
AS
  BEGIN
      INSERT INTO Persons
      SELECT foo,
             bar,
             CASE
               WHEN Len(MyFile) >= 60 THEN MyFile
             END
      FROM   Inserted
  END  

Ответ 2

Вам нужно присоединиться к псевдо-таблице Inserted в инструкции UPDATE. Всегда помните, что SQL Server запускает триггер один раз для оператора, и этот оператор может очень хорошо изменить/вставить несколько строк сразу, поэтому ваша таблица Inserted вполне вероятно будет содержать более одного ряда - просто нужно учитывать это при написании триггера.

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

CREATE TRIGGER trig_MyPplUpdate
ON [Persons]
FOR INSERT
AS
    UPDATE dbo.Persons
    SET MyFile = NULL
    WHERE Len(MyFile) < 60
    AND PersonID IN (SELECT DISTINCT PersonID FROM Inserted)

или использовать любой уникальный столбец (ваш первичный ключ), вы должны получить именно те строки, которые были вставлены.