2014-02-20 186 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