删除单个表时 SQL Server 触发器
Posted
技术标签:
【中文标题】删除单个表时 SQL Server 触发器【英文标题】:SQL Server Trigger On Delete To Single Table 【发布时间】:2017-05-26 04:40:48 【问题描述】:我想在我的数据库中的每个表上创建一个触发器,它将已删除数据的副本记录到一个“审核”表中,然后我可以引用该表。
我环顾四周,但由于列定义不同,似乎找不到将其全部插入单个表的方法。
非常感谢任何帮助。
谢谢
【问题讨论】:
Change Data Capture 可能是更好的方法。 很遗憾,我无法做到这一点,因为我们只使用标准版本的 SQL Server,并且仅在 Enterprise、Developer 和 Enterprise Evaluation 版本中可用 @DaRoGa 一种方法可能是创建一个字符串,然后您可以将其保存到数据库。该字符串的格式可以类似于 columnname: : Oldvalue |NewValue chnaged by : currentuser name 。我在我的一个应用程序中实现了这一点,但需要在每个表触发器上单独完成。如果您愿意,我可以共享一个演示触发器,如果您可以使用这种方法,我的触发器是更新触发器,因此我可以获得新旧值。 如果你能分享那就太好了。这听起来是解决我的问题的合适方法 @DaRoGa : 示例触发器的粘贴代码。看看如果你有任何问题让我知道我很乐意提供帮助。请不要我有更新触发器,但您可以对已删除的触发器有相同的逻辑,希望对您有所帮助。 【参考方案1】:这是一个示例代码。我在这里所做的是用户在表上所做的非常更新我从已删除和已插入表中获取新旧值,当我们更新表时 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 ---------
【讨论】:
【参考方案2】:创建审计表:
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 触发器的主要内容,如果未能解决你的问题,请参考以下文章