Мой первый SQL-триггер в SQL Server 2008 - PullRequest
2 голосов
/ 28 ноября 2011

Я попытался выполнить следующий код, когда натолкнулся на странную ошибку. Я надеюсь, что вы, ребята, можете помочь мне здесь:)

CREATE TRIGGER Vlucht_Duurtussenstop
   ON  dbo.Vlucht
   AFTER UPDATE,INSERT
AS 
BEGIN
 IF (new.Duurtussenstop <> old.Duurtussenstop)
    BEGIN
      EXECUTE dbo.testprocudure1
         @p_vluchtDuurtussenstop = Duurtussenstop
    END
END
GO

Придает

[15:50:03] Gert-Jan Bos: Msg 102, Level 15, State 1, Line 7
Incorrect syntax near ' '.
Msg 102, Level 15, State 1, Line 12
Incorrect syntax near ' '.
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near ' '.

Ответы [ 2 ]

3 голосов
/ 28 ноября 2011

SQL Server не имеет new и old. Он имеет псевдотаблицы inserted и deleted, но они могут содержать несколько строк, если исходный оператор затрагивал несколько строк.

Из вашего использования также неясно, вызывается ли testprocudure1 со старым или новым значением, поэтому я не могу переписать ваш запрос в данный момент.


В идеале тело testprocudure1 можно развернуть в триггере, чтобы избежать необходимости использовать курсор - но для поиска интересующих вас строк запрос будет выглядеть следующим образом:

SELECT i.Duurtussenstop,d.Duurtussenstop
FROM
    inserted i
        join
    deleted d
        on
             i.Col1 = d.Col1 and
             i.Col2 = d.Col2

где я предполагаю, что первичный ключ в таблице (Col1, Col2)

0 голосов
/ 28 ноября 2011

Это плохая практика, чтобы вызывать процесс в триггере. Это особенно плохо, если это процесс, который должен запускать одну запись за раз. Триггеры SQL-сервера действуют на пакеты записей не по одной за раз. Предположим, кто-то обновил 100 000 записей? Что будет с триггером тогда? То, как вы планируете это записать, тогда только одна запись повлияет на результат и будет запущен процесс. Вы можете поместить его в курсор или цикл while, но это может снизить производительность. Или вы можете отказаться от процедуры и использовать решение на основе множеств.

Вы должны планировать эти типы изменений и тестировать их. Вы должны иметь в триггере основанные на множестве процессы без циклов записи, так как медлительность в триггере может остановить всю систему. Производительность имеет решающее значение. Однажды мне пришлось исправить curosr в устаревшей базе данных. Для вставки 40 000 записей потребовалось более 40 минут (и у меня был файл для импорта, в который вставлялись бы миллионы записей). После возврата к вставке на основе набора те же 40 000 записей заняли всего несколько секунд.

При написании triiger вам необходимо протестировать как вставки и обновления одной записи, так и вставки и обновления нескольких записей, даже если вы думаете, что они никогда не произойдут. Потому что рано или поздно они это сделают (например, никто не собирается использовать графический интерфейс для изменения цен на 10 000 записей по одной за раз), и ваш триггер остановит производственную систему, в то время как обработка часов занимает даже часы или даже дни вставить или обновить. Или, в качестве альтернативы, он не будет правильно обрабатывать все записи, а только одну, которая вызовет проблему целостности данных.

...