2014-02-20 179 views
2

我使用SQL Server 2008的創建單觸發插入/更新

假設我有表A這是一個交易表。而表B是歷史表。

每當一個行插入或表A中更新,新的行應於表B.

插入表B的狀態列應分別改變爲插入或更新。

如何從單個觸發器處理這個問題?

+0

表A和B之間有什麼區別? A = B +狀態? – thepirat000

+0

是的。 B具有表A的所有列和一個額外的列狀態。 – 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 

注意 你會得到這個錯誤,如果表B對,因爲我們使用的身份(SELECT *)

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