当表更新或删除行时,我可以通过哪些方式创建存档条目?

时间:2014-09-29 12:23:09

标签: sql-server

我的SQL Server 2012数据库中有一个简单的表

CREATE TABLE [dbo].[Content] (
    [ContentId]       INT            IDENTITY (1, 1) NOT NULL,
    [SubjectId]       INT            NOT NULL,
    [Title]           NVARCHAR (50)  NOT NULL,
    [Text]            NVARCHAR (MAX) NOT NULL,
    [Version]         ROWVERSION     NOT NULL,
    [CreatedBy]       INT            NOT NULL,
    [CreatedDate]     DATETIME       NOT NULL,
    [ModifiedBy]      INT            NOT NULL,
    [ModifiedDate]    DATETIME       NOT NULL,
    CONSTRAINT [PK_Content] PRIMARY KEY CLUSTERED ([ContentId] ASC)
);
GO
CREATE NONCLUSTERED INDEX [Content_Subject_IX]
    ON [dbo].[Content]([SubjectId] ASC);
GO

当用户编辑或删除此表中的数据时,所有更改都将丢失。我真正想要的是以某种方式保留更改。

任何人都可以给我任何建议或指出我可能的解决方案。我接受任何建议,并欢迎一些想法。例如,创建存档表是否合理,如果我这样做,那么我如何从数据库中填充该表。有没有一种简单的方法可以用触发器做到这一点?

我希望有人能指出我正确的方向。我没有DBA要求建议所以我将不胜感激。

3 个答案:

答案 0 :(得分:1)

如果您拥有SQL Server的企业版,则可以使用“更改数据捕获”来保留完整的更改历史记录。从官方文档(Change Data Capture):

更改数据捕获通过捕获DML更改的事实和已更改的实际数据,提供用户表的历史更改信息。通过使用读取事务日志并对系统影响较小的异步进程捕获更改。

答案 1 :(得分:0)

你可以使用触发器执行此操作,但我最喜欢的解决方案是仅执行"软删除"。

软删除意味着您添加一个列,一个名为"删除"的位类型。或者名为" DeletedOn"。

的日期时间列(我的收藏)

当用户"删除"一行,而不是实际删除它,你填充该列。当您查询表格时,请务必过滤掉" DeletedOn"不是空的。这些行被有效删除,但它们仍然用于历史目的。

我看到你已经得到了" ModifiedBy"和" ModifiedOn"。所以你可能会考虑" DeletedBy"和" DeletedOn"

答案 2 :(得分:0)

如果Change Data Capture无效,那么您可以使用CONTEXT_INFOTriggers在更新或删除之前存档数据

DECLARE @ID int,@CONTEXT_INFO varbinary(128)

SET @ID = 10
SET @CONTEXT_INFO =cast('ID='+CONVERT(varchar(10),@ID)
+REPLICATE(' ',128) as varbinary(128))
SET CONTEXT_INFO @CONTEXT_INFO

--do Update / Delete that will fire the trigger

SET CONTEXT_INFO 0x0 

这是检索值的触发器部分:

Create Trigger UpdDel
on Cuttingissue
Instead of Update,Delete
as
Begin
Begin Try

DECLARE @ID     int
       ,@sCONTEXT_INFO  varchar(128)
SELECT @sCONTEXT_INFO=CAST(CONTEXT_INFO() AS VARCHAR) 
FROM master.dbo.SYSPROCESSES WHERE SPID=@@SPID

IF LEFT(@sCONTEXT_INFO,9)='ID'
BEGIN
    SET @ID=RIGHT(RTRIM(@sCONTEXT_INFO),LEN(RTRIM(@sCONTEXT_INFO))-10)
END
ELSE
BEGIN
    RAISERROR('ID was not specified',16,1)
    ROLLBACK TRAN
    RETURN
END
    Insert into Backup_tbl(Pktno,EType,Clg,Class,[Subject],Totscripts,Flag,CiDate)
    Select Pktno,EType,Clg,Class,[Subject],Totscripts,Flag,CiDate 
    from Cuttingissue where Pktno=@ID

/* Do Your Update/Delete here */ 

End Try
Begin Catch
Declare @ErrMsg Nvarchar(max),@Errseverity int
Set @ErrMsg=ERROR_MESSAGE()
Set @Errseverity=ERROR_SEVERITY()

Raiserror(@ErrMsg,@Errseverity,1)

End Catch
End