Подтвердить что ты не робот

Как я могу сделать ДОПОЛНИТЕЛЬНЫЙ триггер с сервером sql?

Я использую Sqlserver express, и я не могу выполнить триггер before updated. Есть ли другой способ сделать это?

4b9b3361

Ответ 1

MSSQL не поддерживает BEFORE триггерами. Наиболее близким является триггеры INSTEAD OF но их поведение отличается от триггеров BEFORE в MySQL.

Вы можете узнать больше о них здесь и заметить, что триггеры INSTEAD OF "Указывает, что триггер выполняется вместо триггерного оператора SQL, таким образом переопределяя действия триггерных операторов". Таким образом, действия по обновлению могут не выполняться, если триггер неправильно записан/обработан. Каскадные действия также затрагиваются.

Вместо этого вы можете использовать другой подход к тому, чего вы пытаетесь достичь.

Ответ 2

Верно, что в MSSQL нет "до триггеров". Тем не менее, вы все равно можете отслеживать изменения, внесенные в таблицу, используя вместе "вставленные" и "удаленные" таблицы. Когда обновление вызывает запуск триггера, "вставленная" таблица сохраняет новые значения, а таблица "удалена" хранит старые значения. Получив эту информацию, вы могли бы относительно легко имитировать поведение "перед триггером".

Ответ 3

T-SQL поддерживает только триггеры AFTER и INSTEAD OF, он не имеет триггера BEFORE, как в некоторых других РСУБД.

Я считаю, что вы захотите использовать триггер INSTEAD OF.

Ответ 4

Не могу быть уверен, что это применимо к SQL Server Express, но вы все равно можете получить доступ к данным "до", даже если ваш триггер происходит после обновления. Вам необходимо прочитать данные из удаленной или вставленной таблицы, которая создается на лету при изменении таблицы. По сути, это то, что говорит @Stamen, но мне все еще нужно было продолжить изучение, чтобы понять этот (полезный!) Ответ.

В удаленной таблице хранятся копии затронутых строк во время операторов DELETE и UPDATE. Во время выполнения оператора DELETE или UPDATE строки удаляются из таблицы триггеров и переносятся в удаленную таблицу...

Вставленная таблица хранит копии затронутых строк во время операторов INSERT и UPDATE. Во время транзакции вставки или обновления новые строки добавляются как во вставленную таблицу, так и в таблицу триггеров...

https://msdn.microsoft.com/en-us/library/ms191300.aspx

Таким образом, вы можете создать свой триггер для чтения данных из одной из этих таблиц, например,

CREATE TRIGGER <TriggerName> ON <TableName>
AFTER UPDATE
AS
  BEGIN
    INSERT INTO <HistoryTable> ( <columns...>, DateChanged )
    SELECT <columns...>, getdate()
    FROM deleted;
  END;

Мой пример основан на следующем:

http://www.seemoredata.com/en/showthread.php?134-Example-of-BEFORE-UPDATE-trigger-in-Sql-Server-good-for-Type-2-dimension-table-updates

Ответ 5

Все "обычные" триггеры в SQL Server являются триггерами "ПОСЛЕ...". Нет триггеров "ПЕРЕД...".

Чтобы сделать что-то перед обновлением, откройте ВМЕСТО ДОБАВЛЕНИЯ Триггеры.

Ответ 6

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

Ответ 7

Чтобы сделать BEFORE UPDATE в SQL Server, я использую трюк. Я делаю ложное обновление записи (UPDATE Table SET Field = Field), таким образом, я получаю предыдущее изображение записи.

Ответ 8

Полный пример:

CREATE TRIGGER [dbo].[trig_020_Original_010_010_Gamechanger]
   ON  [dbo].[T_Original]
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    DECLARE @Old_Gamechanger int;
    DECLARE @New_Gamechanger int;

    -- Insert statements for trigger here
    SELECT @Old_Gamechanger = Gamechanger from DELETED;
    SELECT @New_Gamechanger = Gamechanger from INSERTED;

    IF @Old_Gamechanger != @New_Gamechanger

        BEGIN

            INSERT INTO [dbo].T_History(ChangeDate, Reason, Callcenter_ID, Old_Gamechanger, New_Gamechanger)
            SELECT GETDATE(), 'Time for a change', Callcenter_ID, @Old_Gamechanger, @New_Gamechanger
                FROM deleted
            ;

        END

END