为插入/更新创建单个触发器

时间:2014-02-20 03:15:57

标签: sql-server sql-server-2008

我正在使用SQL Server 2008。

假设我有一个表A,它是一个事务表。和表B是历史表。

每当在表A中插入或更新行时,应在表B中插入新行。

表B的Status列应分别更改为INSERTED或UPDATED。

如何从单个触发器处理此问题?

4 个答案:

答案 0 :(得分:3)

你所要求的很简单:

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
);
哇,到目前为止,有很多彻头彻尾的错误和半错误(至少是过于复杂的)答案。

答案 1 :(得分: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然后再次插入,这将失败)

答案 2 :(得分: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具有标识,您将收到此错误,因为我们使用(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.

答案 3 :(得分:0)

这是经过测试的。员工和员工有相同的表结构.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