Как я могу сделать до обновления триггер с сервером SQL?

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

7 ответов

Решение

MSSQL не поддерживает BEFORE триггеры. Ближайший у вас есть INSTEAD OF триггеры, но их поведение отличается от BEFORE триггеры в MySQL.

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

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

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

Не могу быть уверен, что это применимо к 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

триггеры sql-сервера

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

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

Все "нормальные" триггеры в SQL Server являются триггерами "AFTER ...". Нет триггеров "ДО..."

Чтобы сделать что-то перед обновлением, проверьте триггеры INSTEAD OF UPDATE.

Обновленные или удаленные значения хранятся в DELETED. мы можем получить его с помощью метода ниже в триггере

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

CREATE TRIGGER PRODUCT_UPDATE ON PRODUCTS
FOR UPDATE 
AS
BEGIN
DECLARE @PRODUCT_NAME_OLD VARCHAR(100)
DECLARE @PRODUCT_NAME_NEW VARCHAR(100)

SELECT @PRODUCT_NAME_OLD = product_name from DELETED
SELECT @PRODUCT_NAME_NEW = product_name from INSERTED

END

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

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

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

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
Другие вопросы по тегам