我的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要求建议所以我将不胜感激。
答案 0 :(得分:1)
如果您拥有SQL Server的企业版,则可以使用“更改数据捕获”来保留完整的更改历史记录。从官方文档(Change Data Capture):
更改数据捕获通过捕获DML更改的事实和已更改的实际数据,提供用户表的历史更改信息。通过使用读取事务日志并对系统影响较小的异步进程捕获更改。
答案 1 :(得分:0)
你可以使用触发器执行此操作,但我最喜欢的解决方案是仅执行"软删除"。
软删除意味着您添加一个列,一个名为"删除"的位类型。或者名为" DeletedOn"。
的日期时间列(我的收藏)当用户"删除"一行,而不是实际删除它,你填充该列。当您查询表格时,请务必过滤掉" DeletedOn"不是空的。这些行被有效删除,但它们仍然用于历史目的。
我看到你已经得到了" ModifiedBy"和" ModifiedOn"。所以你可能会考虑" DeletedBy"和" DeletedOn"
答案 2 :(得分:0)
如果Change Data Capture
无效,那么您可以使用CONTEXT_INFO
和Triggers
在更新或删除之前存档数据
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