2014-02-20 3 views
2

Я использую SQL Server 2008.Создание одного триггера для вставки/обновления

Предполагая, что у меня есть таблица A, которая является таблицей транзакций. А таблица B - таблица истории.

Всякий раз, когда строка вставляется или обновлен в таблице А, новая строка должна быть вставлена ​​в таблице B.

В столбце Состояние таблицы B должен измениться на вставке или обновлении соответственно.

Как справиться с этим с помощью одного триггера?

+0

Каковы различия между таблицами А и В? A = B + статус? – thepirat000

+0

Да. B имеет все столбцы таблицы A плюс дополнительный столбец Status. – RKh

ответ

1

То, что вы просите за это довольно просто:

CREATE TRIGGER TR_TableA_IU ON dbo.TableA FOR INSERT, UPDATE 
AS 
SET NOCOUNT ON; 
INSERT dbo.TableB (Column1, Column2, Status) 
SELECT 
    I.Column1, 
    I.Column2, 
    CASE WHEN EXISTS (SELECT * FROM Deleted) THEN 'UPDATED' ELSE 'INSERTED' END 
FROM Inserted I; 

Если вы также хотели обращаться делеции, которые могут быть сделаны в одном операторе, тоже:

CREATE TRIGGER TR_TableA_IUD ON dbo.TableA FOR INSERT, UPDATE, DELETE 
AS 
SET NOCOUNT ON; 
INSERT dbo.TableB (Column1, Column2, Status) 
SELECT 
    I.Column1, 
    I.Column2, 
    CASE WHEN EXISTS (SELECT * FROM Deleted) THEN 'UPDATED' ELSE 'INSERTED' END 
FROM 
    Inserted I 
UNION ALL 
SELECT 
    D.Column1, 
    D.Column2, 
    'DELETED' 
FROM Deleted D 
WHERE NOT EXISTS (
    SELECT * FROM Inserted 
); 

Ого, есть много прямо-неправильных и полуавтоматические неправильных (по крайней мере в том, усложненных) ответов до сих пор.

+0

спасибо за ваш комментарий. Вы можете сделать свой триггер для вставки, обновления, удаления – KumarHarsh

+0

Конечно, вот и все! – ErikE

1

Если предположить, что обе таблицы:

  • есть столбец "Id" в качестве первичного ключа.
  • имеет ту же схему, за исключением того, что в таблице истории есть дополнительный столбец «Статус» в конце.

Вы можете создать триггер, как это:

CREATE TRIGGER dbo.TableA_InsUpd 
ON dbo.TableA 
AFTER INSERT, UPDATE, DELETE 
AS 
BEGIN 
    Insert Into TableB 
    Select i.*, 'INSERTED' 
    From inserted i 
    Where not exists (Select * From deleted d Where d.Id = i.Id) 

    Update B 
    Set [Status] = 'UPDATED', 
    Field1 = i.Field1, 
    Field2 = i.Field2 
    From TableB B 
    Inner Join inserted i On i.Id = B.Id 
    Where exists (Select * From deleted d Where d.Id = i.Id) 

    Update B 
    Set [Status] = 'DELETED' 
    From TableB B 
    Inner Join deleted d On d.Id = B.Id 
    Where not exists (Select * From inserted i Where i.Id = d.Id) 
END 

Here is a SqlFiddle с полным кодом

(Обратите внимание, это будет ошибкой, если запись Id будет удален, а затем снова вставить)

+0

Я уверен, что этот ответ не соответствует требованиям (например, вставить в обновление, а не обновлять при обновлении). – ErikE

+0

Вы правы ... В следующий раз внимательно прочитайте – thepirat000

1

Попробуйте этот код

CREATE TRIGGER YouTriggerName 
    ON TableA 
    AFTER INSERT,DELETE,UPDATE 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for trigger here 
    DECLARE @type NVarChar(15)= 
     CASE when not exists(SELECT * FROM inserted) 
      THEN 'Deleted' 
     WHEN exists(SELECT * FROM deleted) 
      THEN 'Updated' 
     ELSE 
      'Inserted' 
     END 

    /* 
    TableB should contains all the columns of TableA 
    OR tweak it to suit your need 
    */ 
    IF @type = 'Deleted' BEGIN 
     INSERT INTO TableB 
     SELECT *, @type Stat FROM deleted 
    END 
    ELSE BEGIN 
     INSERT INTO TableB 
     SELECT *, @type Stat FROM inserted 
    END 

END 

Примечание вы получите эту ошибку, если TableB имеет идентичность на так как мы используем (выберите *)

An explicit value for the identity column in table 'TableB' can only be specified when a column list is used and IDENTITY_INSERT is ON. 
0

это tested.here работник и работник имеют одну таблицу structure.0 означает обновленное и 1 = вставлен, 2 = удален

 Alter trigger trgTest on dbo.employee 
AFTER INSERT, UPDATE,Delete 
as 
Begin 
Set noCount on 
if exists(select e.id from deleted e inner join inserted i on e.ID=i.id) 
Begin 
insert into Employee1 
select id,name,0 from inserted 
End 
else if exists(select e.id from Employee1 e inner join deleted d on e.ID=d.id) 
Begin 
insert into Employee1 
select id,name,2 from deleted 
End 
else 
Begin 
insert into Employee1 
select id,name,1 from inserted 
End 

End 
+0

Объединения в предложениях EXISTS совершенно не нужны. Второй запрос EXISTS также не нужен. Использование двух отдельных инструкций INSERT не требуется. – ErikE