2016-07-07 3 views
0

Я использую следующий триггер для отслеживания вставок и обновлений на нескольких таблицах и регистрации его в таблице журналов.Триггер для обработки нескольких вставок строк и обновлений

CREATE TRIGGER tr_TestTable1] 
ON [TestTable_1] 
AFTER INSERT, UPDATE 
AS 
DECLARE @keyid int, @tn nvarchar(50), @recEditMode nvarchar(50), @trstat nvarchar(50) 
BEGIN 
    SET NOCOUNT ON; 
    SET @tn = 'TestTable_1' 
    IF EXISTS(SELECT 1 FROM INSERTED) 
    BEGIN 
    SET @recEditMode = (Select REC_EDIT_MODE FROM inserted) 
    SET @trstat = 'PENDING' 
    SET @keyid = (Select prkeyId FROM inserted) 

    IF (@recEditMode = 'MANUAL') 
    BEGIN 
    IF NOT EXISTS (SELECT * FROM [logTable_1] WHERE SourceKeyId = @keyid AND TrStatus = 'PENDING' AND SourceTableName = @tn) 
     BEGIN 
      INSERT INTO [logTable_1](SourceKeyId,SourceTableName,TrStatus) 
       VALUES (@keyid, @tn, @trstat)  
     END 
    END 
     END 

END 

Это прекрасно подходит для однострочной вставки и однострочного обновления. Я не могу оптимизировать этот код, чтобы обрабатывать вставки и обновления нескольких строк. Ищете некоторую помощь в этом.

Спасибо.

+0

Какой РСУБД это? Для триггеров он делает ** огромную ** разницу, используете ли вы MySQL, PostgreSQL, Oracle, SQL Server или IBM DB2 - или еще что-то еще. Добавьте соответствующий тег на свой вопрос! –

+2

Если это для ** SQL Server **, ваш триггер имеет недостаток ** MAJOR **: вы предполагаете, что он будет называться ** один раз в строке ** - это ** НЕ ** случай. Триггер будет срабатывать ** один раз за оператор **, поэтому, если ваш оператор 'INSERT' вставляет 25 строк, триггер запускает ** один раз **, а псевдо-таблица' Inserted' будет содержать 25 строк. Какой из этих 25 строк будет выбран ваш код? 'Выберите prkeyId FROM insert' - он не детерминирован, вы получите ** одну произвольную строку **, и вы будете ** игнорировать все остальные строки **. Для этого нужно переписать триггер! –

+0

Извините за неполную информацию. База данных - это SQL Server, и я понял, что триггер будет срабатывать для каждого оператора. Я пытался отслеживать все строки, соответствующие определенным критериям (recEditMode = 'MANUAL') и записывать их в отдельную таблицу. Мне также нужно записать имя таблицы, поскольку я буду использовать один и тот же триггер для нескольких таблиц. Будучи новичком в этом, я искал некоторую помощь, чтобы переписать триггер, чтобы учесть все затронутые строки. – user2208460

ответ

0

Я изменил триггер, как показано ниже, и это, кажется, работает хорошо сейчас ...

CREATE TRIGGER tr_TestTable1] 
    ON [TestTable_1] 
    AFTER INSERT, UPDATE 
    AS 
    DECLARE @keyid int, @tn nvarchar(50), @trstat nvarchar(50) 
    BEGIN 
     IF @@ROWCOUNT = 0 
     RETURN 
     SET NOCOUNT ON; 
     IF EXISTS(SELECT * FROM INSERTED) 
     BEGIN 
     SET @tn = 'TestTable_1' 
     SET @trstat = 'PENDING' 
     BEGIN 
     INSERT INTO LogTable_1 (SourceKeyId, SourceTableName, TrStatus) 
     SELECT I.prKeyId, @tn, @trStat FROM INSERTED AS I 
     WHERE (I.REC_EDIT_MODE = 'MANUAL' AND NOT EXISTS(SELECT * FROM LogTable_1 WHERE SourceKeyId = I.prKeyId AND SourceTableName = @tn AND TrStatus = 'PENDING')) 

     END 
    END 
END 
Смежные вопросы