два включает, вставляют той же таблицы

Вот одна очень интересная проблема. Я использую SQL Server 2008. Я имею два, включает одну общую таблицу, заявляют 'CommonTable'. один триггер находится на обновлении, и другой идет, вставляют/обновляют/удаляют.

  • В первом триггере "Trigger1" я делаю проверки/откат когда-то изменяют новое вставленное значение на основе бизнес-логики. вот пример кода

-

CREATE TRIGGER [dbo].[Trigger1] ON [dbo].[CommonTable]
FOR UPDATE
UPDATE [CommonTable] 
SET 
    [StatusCode] = 'New Value'
WHERE 
[RecId] = 'rec id value'
  • Во втором триггере "Trigger2" я храню новое вставленное/удаленное/обновленное значение от таблицы 'CommonTable' до другой таблицы 'CommonTable_History' для истории, отслеживающей цель. вот пример кода

-

CREATE TRIGGER [dbo].[Trigger2] ON [dbo].[CommonTable]
FOR INSERT, UPDATE, DELETE

--based on logic read the value from DELETED or INSERTED table and store in other table.

SELECT @RowData = (SELECT * FROM DELETED AS [CommonTable] WHERE [RecId] = @RowRecId FOR XML AUTO,                       BINARY BASE64 , ELEMENTS)

--and then insert @RowData in 'CommonTable_History' table.

С помощью 'sp_settriggerorder' я установил порядок выполнения этих триггеров, поэтому первый "Trigger1" выполняется и затем "Trigger2".

Второй триггер работы "Trigger2" хорошо для вставляет/удаляет значения. Это хорошо работает для нового вставленного значения, если новые вставленные значения не были изменены первым триггером "Trigger1".

Но если в некоторых случаях, вставленные значения были изменены в "Trigger1". скажите [Код состояния] = 'Новое Значение', и старые значения было 'Старое Значение' затем, "Trigger2" все еще хранят 'Старое Значение' вместо 'Нового Значения'. Почему, потому что "Trigger1" изменяют значение, но то значение все еще не было хранилищем в базе данных и прежде чем тот "Trigger2" выполняется на Вставке. Теперь мое требование, здесь я хочу сохранить "Новое Значение".

Таким образом, я думал, позволяет, делают "Trigger2" для использования "ПОСЛЕ" ключевых слов. Но "ДЛЯ" и "ПОСЛЕ" ведут себя, то же не могло решить проблему.

Затем я думал, позволяет, делают "Trigger2" для использования ключевого слова "INSTEAD OF". Но "INSTEAD OF" дает следующую ошибку, "Не может СОЗДАТЬ INSTEAD OF, УДАЛЯЮТ или ТРИГГЕР ОБНОВЛЕНИЯ INSTEAD OF. Это вызвано тем, что таблица имеет FOREIGN KEY с каскадным удалением или ОБНОВЛЕНИЕМ".

Я не могу удалить FOREIGN KEY с каскадным удалением или ОБНОВЛЕНИЕМ для таблицы 'CommonTable'.

Сообщите мне, есть ли у Вас люди какое-либо другое альтернативное решение. - Vikram Gehlot

5
задан Toby Allen 16 July 2010 в 20:52
поделиться

3 ответа

Я думаю, что ваш второй триггер должен использовать значения из реальной таблицы, а не из вставленных / удаленных таблиц для заполнения таблицы журнала - вставленные / удаленные всегда будут иметь неизмененные исходные значения, а Ваши измененные значения появятся в таблице. Сделайте второй триггер триггером «После», чтобы вам не пришлось использовать sp_settriggerorder. Так, например:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[trg_Trig1] 
   ON  [dbo].[TestTable] 
   FOR INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    update TestTable
    set [value] = 10
    where [value] = 25

END

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[trg_Trig2]
   ON  [dbo].[TestTable] 
   AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    insert into log_TestTable
    (id, description, [value])
    select tt.id, tt.description, tt.[value]
    from inserted i
        LEFT JOIN TestTable tt
            ON tt.id = i.id

END
3
ответ дан 14 December 2019 в 18:54
поделиться

Возможно, это не самое чистое решение, но можно ли просто объединить два триггера в один? Таким образом, обе части SQL будут знать об изменениях друг друга.

2
ответ дан 14 December 2019 в 18:54
поделиться

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

Вместо select * from deleted, почему бы не присоединить таблицу deleted или inserted к исходной таблице и взять значения оттуда (за исключением значения id, которое вы получаете из deleted или inserted, это должно дать вам самые актуальные значения всех файлов, и если вы добавите другую логику триггера позже, она не сломается.

0
ответ дан 14 December 2019 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: