Sql server 删除到单个表时的SQL Server触发器

Sql server 删除到单个表时的SQL Server触发器,sql-server,triggers,audit,Sql Server,Triggers,Audit,我想在数据库中的每个表上创建一个触发器,将删除数据的副本记录到一个“审计”表中,然后我可以引用该表 我环顾了一下四周,但由于列定义不同,似乎找不到将其全部插入单个表的方法 非常感谢您的帮助 谢谢这是一个示例代码。我在这里所做的是用户对表所做的更新,我从删除和插入的表中获取新旧值,sql在更新表时维护这些值。对于删除的情况,我认为您可以从删除中获取 ALTER TRIGGER [SIR].[TESTTABLE_UPDATE] ON [DBO].[TESTTABLE] AFT

我想在数据库中的每个表上创建一个触发器,将删除数据的副本记录到一个“审计”表中,然后我可以引用该表

我环顾了一下四周,但由于列定义不同,似乎找不到将其全部插入单个表的方法

非常感谢您的帮助


谢谢这是一个示例代码。我在这里所做的是用户对表所做的更新,我从删除和插入的表中获取新旧值,sql在更新表时维护这些值。对于删除的情况,我认为您可以从删除中获取

  ALTER TRIGGER [SIR].[TESTTABLE_UPDATE]
        ON [DBO].[TESTTABLE]
  AFTER UPDATE
  AS
  BEGIN
         IF (@@ROWCOUNT  = 0)  return SET NOCOUNT ON; DECLARE @USER VARCHAR(1000)  
         -- this is a function which can gives u current loggined user in case if someone update the data from backend we can get that user name and log it.
         SET @USER='' SET @USER= (select dbo.GetCurrentUserName())  

         --this is a filter for bulk update which systemm does and you dont care about it so return 
         if( PATINDEX('%workerprocess%',@USER)>0) return 

         DECLARE  @ID INT , @LOGS VARCHAR(MAX)  , @FINALLOGS VARCHAR(MAX)      DECLARE @ACTION VARCHAR(MAX)       
         SET @ACTION =''       SET @LOGS=''      SET @FINALLOGS =''  
         SELECT  @LOGS = DELETED.CHANGELOG FROM DELETED
    -- individual column that a table contain 
    IF UPDATE([STATECODE])
        BEGIN
            SET @Action += '|  StateCode Changed from '+convert(varchar, ( select isnull( [STATECODE],'') FROM deleted   )) +'  to  '+ convert(varchar, ( select isnull( [STATECODE],'') FROM inserted  ))  +' | '
        END
   -- individual column that a table contain 
    IF UPDATE([FACILITYCODE])
        BEGIN
            SET @Action += '|  FacilityCode Changed from '+convert(varchar, ( select isnull( [FACILITYCODE],'') FROM deleted   )) +'  to  '+ convert(varchar, ( select isnull( [FACILITYCODE],'') FROM inserted  ))  +' | '
        END

    IF UPDATE([INSTALLATIONCODE])
        BEGIN
            SET @Action += '|  InstallationCode Changed from '+convert(varchar, ( select isnull( [INSTALLATIONCODE],'') FROM deleted   )) +'  to  '+ convert(varchar, ( select isnull( [INSTALLATIONCODE],'') FROM inserted  ))  +' | '
        END


             set @FINALLOGS =' [SIR.INSTALLATIONS Updated  On ' +  CONVERT(varchar(25), GETDATE()) + @ACTION + ISNULL( @LOGS,'') +' ] '



             -- this is my audit table where I am logging everything.
             INSERT INTO SIR.UserChangeLog (UpdatedBy,ChangeLog)  VALUES(@user, @FINALLOGS)
  END
 ---- End  tirgger   ---------

这是一个示例代码。我在这里所做的是用户对表所做的更新,我从删除和插入的表中获取新旧值,sql在更新表时维护这些值。对于删除的情况,我认为您可以从删除中获取

  ALTER TRIGGER [SIR].[TESTTABLE_UPDATE]
        ON [DBO].[TESTTABLE]
  AFTER UPDATE
  AS
  BEGIN
         IF (@@ROWCOUNT  = 0)  return SET NOCOUNT ON; DECLARE @USER VARCHAR(1000)  
         -- this is a function which can gives u current loggined user in case if someone update the data from backend we can get that user name and log it.
         SET @USER='' SET @USER= (select dbo.GetCurrentUserName())  

         --this is a filter for bulk update which systemm does and you dont care about it so return 
         if( PATINDEX('%workerprocess%',@USER)>0) return 

         DECLARE  @ID INT , @LOGS VARCHAR(MAX)  , @FINALLOGS VARCHAR(MAX)      DECLARE @ACTION VARCHAR(MAX)       
         SET @ACTION =''       SET @LOGS=''      SET @FINALLOGS =''  
         SELECT  @LOGS = DELETED.CHANGELOG FROM DELETED
    -- individual column that a table contain 
    IF UPDATE([STATECODE])
        BEGIN
            SET @Action += '|  StateCode Changed from '+convert(varchar, ( select isnull( [STATECODE],'') FROM deleted   )) +'  to  '+ convert(varchar, ( select isnull( [STATECODE],'') FROM inserted  ))  +' | '
        END
   -- individual column that a table contain 
    IF UPDATE([FACILITYCODE])
        BEGIN
            SET @Action += '|  FacilityCode Changed from '+convert(varchar, ( select isnull( [FACILITYCODE],'') FROM deleted   )) +'  to  '+ convert(varchar, ( select isnull( [FACILITYCODE],'') FROM inserted  ))  +' | '
        END

    IF UPDATE([INSTALLATIONCODE])
        BEGIN
            SET @Action += '|  InstallationCode Changed from '+convert(varchar, ( select isnull( [INSTALLATIONCODE],'') FROM deleted   )) +'  to  '+ convert(varchar, ( select isnull( [INSTALLATIONCODE],'') FROM inserted  ))  +' | '
        END


             set @FINALLOGS =' [SIR.INSTALLATIONS Updated  On ' +  CONVERT(varchar(25), GETDATE()) + @ACTION + ISNULL( @LOGS,'') +' ] '



             -- this is my audit table where I am logging everything.
             INSERT INTO SIR.UserChangeLog (UpdatedBy,ChangeLog)  VALUES(@user, @FINALLOGS)
  END
 ---- End  tirgger   ---------
创建审核表:

CREATE TABLE [dbo].[MyAudit](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [TableName] [nvarchar](100) NOT NULL,
    [ColumnName] [nvarchar](100) NOT NULL,
    [DeletedValue] [sql_variant] NULL,
    [ChangeDateTime] [datetime] NOT NULL,
)
GO
ALTER TABLE [dbo].[MyAudit] ADD  CONSTRAINT [DF_MyAudit_ChangeDateTime]  DEFAULT (getdate()) FOR [ChangeDateTime]
将触发器添加到要记录删除操作的每个表:

CREATE TRIGGER [MyTrigger] 
   ON  [MyTable]
   AFTER DELETE
AS 
BEGIN
    SET NOCOUNT ON;
    Insert into [MyAudit] ([Tablename], [ColumnName], [DeletedValue])
        Select 'MyTable', 'Column1', deleted.Column1 from deleted
    Insert into [MyAudit] ([Tablename], [ColumnName], [DeletedValue])
        Select 'MyTable', 'Column2', deleted.Column2 from deleted
--Do all columns until column x
    Insert into [MyAudit] ([Tablename], [ColumnName], [DeletedValue])
        Select 'MyTable', 'ColumnX', deleted.ColumnX from deleted
END
创建审核表:

CREATE TABLE [dbo].[MyAudit](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [TableName] [nvarchar](100) NOT NULL,
    [ColumnName] [nvarchar](100) NOT NULL,
    [DeletedValue] [sql_variant] NULL,
    [ChangeDateTime] [datetime] NOT NULL,
)
GO
ALTER TABLE [dbo].[MyAudit] ADD  CONSTRAINT [DF_MyAudit_ChangeDateTime]  DEFAULT (getdate()) FOR [ChangeDateTime]
将触发器添加到要记录删除操作的每个表:

CREATE TRIGGER [MyTrigger] 
   ON  [MyTable]
   AFTER DELETE
AS 
BEGIN
    SET NOCOUNT ON;
    Insert into [MyAudit] ([Tablename], [ColumnName], [DeletedValue])
        Select 'MyTable', 'Column1', deleted.Column1 from deleted
    Insert into [MyAudit] ([Tablename], [ColumnName], [DeletedValue])
        Select 'MyTable', 'Column2', deleted.Column2 from deleted
--Do all columns until column x
    Insert into [MyAudit] ([Tablename], [ColumnName], [DeletedValue])
        Select 'MyTable', 'ColumnX', deleted.ColumnX from deleted
END

可能是一种更好的方法。不幸的是,我无法做到这一点,因为我们只使用标准版本的SQL Server,并且该版本仅在企业、开发人员和企业评估中可用editions@DaRoGa一种方法可能是创建一个字符串,然后将其保存到数据库中。字符串的格式可以类似于{columnname:}:Oldvalue | NewValue{chnaged by:}currentuser name。我在我的一个应用程序中实现了这一点,但它需要在每个表触发器上单独完成。如果你喜欢,我可以分享一个相同的演示触发器,如果这个方法对你合适,我的触发器是更新触发器,这样我就可以得到旧的和新的值。如果你能分享,那就太好了。这听起来是一个适合我的方法issue@DaRoGa:粘贴的示例触发器代码。看一看,如果你有任何问题,让我知道我很乐意帮助。请不要,我有一个更新触发器,但你可以在删除一个相同的逻辑,我希望它能帮助你。可能是一种更好的方法。不幸的是,我无法做到这一点,因为我们只使用标准版本的SQL Server,并且该版本仅在企业、开发人员和企业评估中可用editions@DaRoGa一种方法可能是创建一个字符串,然后将其保存到数据库中。字符串的格式可以类似于{columnname:}:Oldvalue | NewValue{chnaged by:}currentuser name。我在我的一个应用程序中实现了这一点,但它需要在每个表触发器上单独完成。如果你喜欢,我可以分享一个相同的演示触发器,如果这个方法对你合适,我的触发器是更新触发器,这样我就可以得到旧的和新的值。如果你能分享,那就太好了。这听起来是一个适合我的方法issue@DaRoGa:粘贴的示例触发器代码。看一看,如果你有任何问题,让我知道我很乐意帮助。请不要,我有一个更新触发器,但你可以在删除一个相同的逻辑,我希望它能帮助你。