创建一个触发器,在更新列时将值插入新表中

时间:2012-03-29 19:08:20

标签: sql sql-server sql-server-2008 triggers

我一直在寻找以前关于触发器的一些答案,但找不到我需要的东西,但我确信我的问题之前已经被问过/回答了。

我正在尝试跟踪table1中columnA和columnB的任何更改。

如果此值发生更改,我希望通过将现有值和新值插入带有日期的其他表来跟踪值。

我一直在考虑使用类似的东西来插入但不确定如何添加获取源表(table1)的现有值和新值:

CREATE TRIGGER NewTrigger ON table1
FOR INSERT
AS

INSERT INTO table2
        (columnA , columnB, todaysDate)
    .
    .

go

我需要使用(我认为)

Before update ON table1 FOR EACH ROW
   .
   .
   .
BEGIN

并查看所有更改并首先插入这些更改,然后在更新后执行相同的操作?

4 个答案:

答案 0 :(得分:11)

这样的事情应该做你需要的。您将在下面的INSERT语句中插入值,以指示在MyLogTable中执行的操作。

CREATE TRIGGER [dbo].[TRIG_MyTable]
ON [dbo].[MyTable]
AFTER INSERT, UPDATE

AS 

DECLARE @INS int, @DEL int

SELECT @INS = COUNT(*) FROM INSERTED
SELECT @DEL = COUNT(*) FROM DELETED

IF @INS > 0 AND @DEL > 0 
BEGIN

    -- a record got updated, so log accordingly.

    INSERT INTO MyLogTable
    SELECT 'New Values', getdate() FROM INSERTED

    INSERT INTO MyLogTable
    SELECT 'Old Values', getdate() FROM DELETED

END

ELSE 
BEGIN

    -- a new record was inserted.

    INSERT INTO MyLogTable
    SELECT 'Insert', getdate() FROM INSERTED

END

如果您愿意,还可以将INSERTEDDELETED中的列添加到日志表中,如果您想捕获插入或更新的实际列值。

答案 1 :(得分:5)

这适用于所有更改和所有列,但您可以修改自己喜欢的方式:

USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER [dbo].[trMyTrigger]
ON [dbo].[MyTable]
AFTER INSERT, UPDATE, DELETE
NOT FOR REPLICATION
AS
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with caller queries select statements.
    -- if an update/insert/delete occurs on the main table, the number of records affected
    -- should only be based on that table and not what records the triggers may/may not
    -- select.
SET NOCOUNT ON;

    -- Determine if this is an insert,update, or delete action

    DECLARE @action AS CHAR(1)
    DECLARE @count AS INT
    SET @action = 'I' -- SET action to 'I'NSERT by default.
    SELECT @count = count(*) FROM DELETED
    IF @count > 0
        BEGIN
            SET @action= 'D' -- SET action to 'D'ELETED.
            SELECT @count = count(*) FROM INSERTED
            IF @count > 0
                SET @action = 'U' -- SET action to 'U'PDATED.
        END

    IF @action = 'D'
        -- THIS IS A DELETE RECORD ACTION
        BEGIN
            INSERT INTO myBackupTable
        SELECT *,GETDATE() AS changeDate, 'DELETE' AS task FROM DELETED
        END
    ELSE
        BEGIN
            IF @action = 'I'
                 -- this is an INSERT record action
                BEGIN
                    INSERT INTO myBackupTable
                    SELECT *,GETDATE() AS changeDate, 'INSERT' as task FROM INSERTED
                END
             ELSE
                -- this is an UPDATE record action
                BEGIN
                    INSERT INTO myBackupTable
                    SELECT *,GETDATE() AS changeDate, 'UPDATE' as task  FROM INSERTED
                END
        END

答案 2 :(得分:1)

在abs上创建触发器触发器 而不是更新为

declare @idd int , @pricee money
  select @idd= ProductID from inserted 
  select @pricee = ListPrice from inserted 
  insert into prod values ( @idd , @pricee)
  print ' cannot change'

答案 3 :(得分:0)

CREATE TRIGGER [dbo].[TRIG_MyTable]
ON [dbo].[MyTable]
AFTER INSERT, UPDATE

AS 

DECLARE @INS int, @DEL int

SELECT @INS = COUNT(*) FROM INSERTED
SELECT @DEL = COUNT(*) FROM DELETED

IF @INS > 0 AND @DEL > 0 
BEGIN

    -- a record got updated, so log accordingly.

    INSERT INTO MyLogTable
    SELECT 'New Values', getdate() FROM INSERTED

    INSERT INTO MyLogTable
    SELECT 'Old Values', getdate() FROM DELETED

END

ELSE 
BEGIN

    -- a new record was inserted.

    INSERT INTO MyLogTable
    SELECT 'Insert', getdate() FROM INSERTED

END