- 浏览: 714681 次
- 性别:
- 来自: 上海
最新评论
-
TheUniqueGirl:
Tomcat系统架构与设计模式:http://www.doci ...
Tomcat -
aykjy:
...
UML常见工具之NetBeans(downmoon) -
不老肖邦:
谢谢提供的简单示例
JAVA toString()
SQL Server 2008中新增的变更数据捕获(CDC)和更改跟踪
本文主要介绍SQL Server中记录数据变更的四个方法:触发器、Output子句、变更数据捕获(Change Data Capture 即CDC)功能、同步更改跟踪。其中后两个为SQL Server 2008所新增。
一、触发器
在SQL Server的早期版本中,如果要记录某个表或视图的Insert/Update/Delete操作,我们可以借助触发器(Trigger)(http://msdn.microsoft.com/zh-cn/library/ms189799.aspx), 这在数据量较小的情况下往往是有效的方式之一,其中后触发器(After Trigger)只能跟踪表的三个操作中的任意组合,而前触发器(Instead Of trigger)可以处理表和视图的更新(即使普通的Update View语句在某些列不明确的情况下报错)。我们看两个例子:
准备基础数据:
USE testDb2 GO --创建两个测试表 IF NOT OBJECT_ID('DepartDemo') IS NULL DROP TABLE [DepartDemo] GO IF NOT OBJECT_ID('DepartChangeLogs') IS NULL DROP TABLE [DepartChangeLogs] GO --测试表 CREATE TABLE [dbo].[DepartDemo]( [DID] [int] IDENTITY(101,1) NOT NULL PRIMARY KEY, [DName] [nvarchar](200) NULL, [DCode] [nvarchar](500) NULL, [Manager] [nvarchar](50) NULL, [ParentID] [int] NOT NULL DEFAULT ((0)), [AddUser] [nvarchar](50) NULL, [AddTime] [datetime] NULL, [ModUser] [nvarchar](50) NULL, [ModTime] [datetime] NULL, [CurState] [smallint] NOT NULL DEFAULT ((0)), [Remark] [nvarchar](500) NULL, [F1] [int] NOT NULL DEFAULT ((0)), [F2] [nvarchar](300) NULL ) GO --记录日志表 CREATE TABLE [DepartChangeLogs] ([LogID] [bigint] IDENTITY(1001,1) NOT NULL PRIMARY KEY, [DID] [int] NOT NULL, [DName] [nvarchar](200) NULL, [DCode] [nvarchar](500) NULL, [Manager] [nvarchar](50) NULL, [ParentID] [int] NOT NULL DEFAULT ((0)), [AddUser] [nvarchar](50) NULL, [AddTime] [datetime] NULL, [ModUser] [nvarchar](50) NULL, [ModTime] [datetime] NULL, [CurState] [smallint] NOT NULL DEFAULT ((0)), [Remark] [nvarchar](500) NULL, [F1] [int] NOT NULL DEFAULT ((0)), [F2] [nvarchar](300) NULL, [LogTime] DateTime Default(Getdate()) Not Null, [InsOrUpd] char not null ) GO
创建触发器:
/******* 创建一个After DML触发器 ******/ /********* 3w@live.cn 邀月***************/ CREATE TRIGGER dbo.tri_LogDepartDemo ON [dbo].[DepartDemo] AFTER INSERT, Delete /************此处使用update与“Insert,Delete”效果是一样的,邀月注 **********/ AS SET NOCOUNT ON --屏蔽触发器发送“受影响的行数”给应用程序 -- Inserted rows INSERT [DepartChangeLogs] (DID,[DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2], LogTime, InsOrUPD) SELECT DISTINCT DID,[DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2], GETDATE(), 'I' FROM inserted i -- Deleted rows INSERT [DepartChangeLogs] (DID,[DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2], LogTime, InsOrUPD) SELECT DISTINCT DID,[DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2], GETDATE(), 'D' FROM deleted d GO INSERT [dbo].[DepartDemo] ([DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2]) VALUES (N'国家统计局房产审计一科', N'0', N'胡不归', 0, N'DeomUser', CAST(0x00009DF7017B6F96 AS DateTime), N'', CAST(0x0000000000000000 AS DateTime), 1, N'专业评估全国房价,为老百姓谋福祉', 0, N'') GO ----该Update不会被触发器记录,但Update会生效 UPDATE departDemo SET [Manager]='任我行' WHERE DID=101 GO DELETE FROM departDemo where DID=101 GO SELECT * FROM [DepartChangeLogs]统计效果:
如果你觉得触发器过于浪费,你可以试着根据某些字段以缩小触发器的范围
/********* 使用DML触发器记录特定列的修改 ***/ /********* 3w@live.cn 邀月***************/ CREATE TRIGGER dbo.[tri_LogDepartDemo2] ON [dbo].[DepartDemo] AFTER Update AS IF Update([Manager]) Begin print '该部门主管实行终身任免制,不得中途更改!' Rollback ----回滚Update操作 End GO UPDATE departDemo SET [Manager]='任我行' WHERE DID=101 GO执行结果:
但触发器的缺陷也是显而易见的,使用触发器请注意以下几点:
1、触发器通常很隐蔽,换句话说,易忘记,特别在检查性能和逻辑问题时。
2、长时间运行的触发器会严重减慢数据操作,特别是在数据频繁修改的数据库中。
3、不记录日志的更新不会引起DML触发器的触发(如WRITETEXT、Trunacte table及批量插入操作)。
4、约束通常比触发器运行更快。
5、处理某些逻辑时,存储过程通常比触发器要更易维护和管理。
6、不允许在触发器中使用Select返回结果集。
关于触发器的更多内容,请看MSDN(http://msdn.microsoft.com/zh-cn/library/ms189799.aspx)
二、使用Output子句
官方解释:OutPut子句(http://technet.microsoft.com/zh-cn/library/ms177564.aspx)返回受 INSERT、UPDATE、DELETE 或 MERGE 语句影响的各行中的信息,或返回基于受这些语句影响的各行的表达式。 这些结果可以返回到处理应用程序,以供在确认消息、存档以及其他类似的应用程序要求中使用。 也可以将这些结果插入表或表变量。 另外,您可以捕获嵌入的 INSERT、UPDATE、DELETE 或 MERGE 语句中 OUTPUT 子句的结果,然后将这些结果插入目标表或视图。
举例:
/********* 使用Output记录表记录的修改 *****/ /********* 3w@live.cn 邀月***************/ ----删除前面的触发器 Drop TRIGGER dbo.[tri_LogDepartDemo] DROP TRIGGER dbo.[tri_LogDepartDemo2] INSERT [dbo].[DepartDemo] ([DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2]) OUTPUT Inserted.*,getdate(),'I' ---注意这行是新增的 INTO DepartChangeLogs ---注意这行是新增的 VALUES (N'发改委', N'0', N'向问天', 0, N'DeomUser', CAST(0x00009DF7017B6F96 AS DateTime), N'', CAST(0x0000000000000000 AS DateTime), 1, N'油价,我说了算', 0, N'') GO SELECT * FROM [DepartChangeLogs]
注意:
1、从OUTPUT 中返回的列反映 INSERT、UPDATE 或 DELETE 语句完成之后但在触发器执行之前的数据。
2、SQL Server 并不保证由使用 OUTPUT 子句的 DML 语句处理和返回行的顺序。
3、与触发器相比,OutPut子句可以直接处理Merge语句。
以上两种方法各有千秋,在合适的情况下采取合适的方法才是明智的选择,令人惊喜的是,SQL Server 2008起,为我们提供了更为强大的内建的方法-变更数据捕获(CDC,http://msdn.microsoft.com/zh-cn/library/bb500244%28v=sql.100%29.aspx)和更改跟踪,下面我们隆重介绍它们。
三、使用“变更数据捕获”(CDC)功能
SQL Server 2008提供了内建的方法“”变更数据捕获“”(Change Data Capture 即CDC)以实现异步跟踪用户表的数据修改,而且这一功能拥有最小的性能开销。可以用于其他数据源的持续更新,例如将OLTP数据库中的数据变更迁移到数据仓库数据库。
要使用CDC功能,首先我们得在数据库中启用该功能。在此我们沿用上例中使用的数据库Testdb2
/**************异步跟踪数据更新演示*************/ /************* 3w@live.cn 邀月***************/ use master GO IF EXISTS (SELECT [name] FROM sys.databases WHERE name = 'TestDb2') drop DATABASE TestDb2 Go CREATE DATABASE TestDb2 GO --查看是否启用CDC SELECT is_cdc_enabled FROM sys.databases WHERE name = 'TestDb2' USE TestDb2 GO ----启用当前数据库的CDC功能 EXEC sys.sp_cdc_enable_db GO /************** 如果报15517错误,请换用其他owner,邀月注 ******/ SELECT is_cdc_enabled FROM sys.databases WHERE name = 'TestDb2' /* is_cdc_enabled 1 */ USE testDb2 GO CREATE TABLE [dbo].[DepartDemo]( [DID] [int] IDENTITY(101,1) NOT NULL PRIMARY KEY, [DName] [nvarchar](200) NULL, [DCode] [nvarchar](500) NULL, [Manager] [nvarchar](50) NULL, [ParentID] [int] NOT NULL DEFAULT ((0)), [AddUser] [nvarchar](50) NULL, [AddTime] [datetime] NULL, [ModUser] [nvarchar](50) NULL, [ModTime] [datetime] NULL, [CurState] [smallint] NOT NULL DEFAULT ((0)), [Remark] [nvarchar](500) NULL, [F1] [int] NOT NULL DEFAULT ((0)), [F2] [nvarchar](300) NULL ) GO /********************************** 需要启用SQL Server Agent服务,否则会报错,邀月注 SQLServerAgent is not currently running so it cannot be notified of this action. ***********************************/ /****** 捕获所有的行变更,只返回行的净变更,其他默认 *******/ EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', @source_name = 'DepartDemo', @role_name = NULL, @capture_instance = NULL, @supports_net_changes = 1, @index_name = NULL, @captured_column_list = NULL, @filegroup_name = default
注意此时,SQL Server 自启动了两个job,一个捕获,一个清除,注意清除是默认凌晨2点,清除72小时以上的数据。如果同一数据库的表中CDC已经启用,不会重建job。
/* Job 'cdc.TestDb2_capture' started successfully. Job 'cdc.TestDb2_cleanup' started successfully. */ --确认表已经被跟踪 SELECT is_tracked_by_cdc FROM sys.tables WHERE name = 'DepartDemo' and schema_id = SCHEMA_ID('dbo') /* is_tracked_by_cdc 1 */ --确认 EXEC sys.sp_cdc_help_change_data_capture 'dbo', 'DepartDemo'
增加了一个表[cdc].[dbo_DepartDemo_CT]
相比源表多了个字段:
[__$start_lsn]
,[__$end_lsn]
,[__$seqval]
,[__$operation]
,[__$update_mask]
不建议直接查询该表,而应该使用下面的技巧:
USE TestDb2 GO INSERT [dbo].[DepartDemo] ([DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2]) VALUES (N'银监会', N'0', N'云中鹤', 0, N'DemoUser1', CAST(0x00009DF7017B6F96 AS DateTime), N'', CAST(0x0000000000000000 AS DateTime), 1, N'监管汇率', 0, N'') INSERT [dbo].[DepartDemo] ([DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2]) VALUES (N'统计局', N'0', N'神算子', 0, N'DemoUser2', CAST(0x00009DF7017B6F96 AS DateTime), N'', CAST(0x0000000000000000 AS DateTime), 1, N'统计数据', 0, N'') GO UPDATE [dbo].[DepartDemo] SET Manager='段正淳' WHERE DID =101 DELETE [dbo].[DepartDemo] WHERE DID = 102
要查询变更,我们需要借助大名鼎鼎的日志序列号(Log Sequence Numbers)即LSN(http://msdn.microsoft.com/zh-cn/library/ms190411%28v=sql.100%29.aspx)来实现LSN级别的跟踪数据变更。 下面示例中sys.fn_cdc_map_time_to_lsn(http://msdn.microsoft.com/zh-cn/library/bb500137%28v=sql.100%29.aspx)用于LSN转换为时间。
/******* 使用LSN 查看CDC记录 *********/ --http://msdn.microsoft.com/zh-cn/library/bb500137%28v=sql.100%29.aspx SELECT sys.fn_cdc_map_time_to_lsn ( 'smallest greater than or equal' , '2012-04-09 16:09:30') as BeginLSN /* BeginLSN 0x0000002C000000AA0003 */ SELECT sys.fn_cdc_map_time_to_lsn ( 'largest less than or equal' , '2012-04-09 23:59:59') as EndLSN /* EndLSN 0x0000002C000001C20005 */ /**************查看所有CDC记录*************/ /************* 3w@live.cn 邀月***************/ DECLARE @FromLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'smallest greater than or equal' , '2012-04-09 16:09:30') DECLARE @ToLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'largest less than or equal' , '2012-04-09 23:59:59') SELECT __$operation, __$update_mask, DID, DName, Manager FROM [cdc].[fn_cdc_get_all_changes_dbo_DepartDemo] (@FromLSN, @ToLSN, 'all') /************查看所有更新************************* __$operation __$update_mask DID DName Manager 2 0x1FFF 105 银监会 云中鹤 2 0x1FFF 106 统计局 神算子 1 0x1FFF 101 银监会 段正淳 1 0x1FFF 103 银监会 云中鹤 1 0x1FFF 104 统计局 神算子 1 0x1FFF 105 银监会 云中鹤 1 0x1FFF 106 统计局 神算子 2 0x1FFF 107 银监会 云中鹤 2 0x1FFF 108 统计局 神算子 4 0x0008 107 银监会 段正淳 1 0x1FFF 108 统计局 神算子 */ /**************查看所有CDC记录*************/ /************* 3w@live.cn 邀月***************/ DECLARE @FromLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'smallest greater than or equal' , '2012-04-09 16:09:30') DECLARE @ToLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'largest less than or equal' , '2012-04-09 23:59:59') --解释一下Operation的具体含义 SELECT CASE __$operation WHEN 1 THEN 'DELETE' WHEN 2 THEN 'INSERT' WHEN 3 THEN 'Before UPDATE' WHEN 4 THEN 'After UPDATE' END Operation, __$update_mask, DID, DName, Manager FROM [cdc].[fn_cdc_get_all_changes_dbo_DepartDemo] (@FromLSN, @ToLSN, 'all update old')
/**************查看净更改(Net changes)CDC记录*************/ /************* 3w@live.cn 邀月 ***************/ INSERT [dbo].[DepartDemo] ([DName], [DCode], [Manager], [ParentID], [AddUser], [AddTime], [ModUser], [ModTime], [CurState], [Remark], [F1], [F2]) VALUES (N'药监局', N'0', N'蝶谷医仙', 0, N'DemoUser3', CAST(0x00009DF7017B6F96 AS DateTime), N'', CAST(0x0000000000000000 AS DateTime), 1, N'制定药价', 0, N'') GO UPDATE [dbo].[DepartDemo] SET Manager='胡青牛' WHERE DID =109 DECLARE @FromLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'smallest greater than or equal' , '2012-04-09 16:09:30') DECLARE @ToLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'largest less than or equal' , '2012-04-09 23:59:59') SELECT CASE __$operation WHEN 1 THEN 'DELETE' WHEN 2 THEN 'INSERT' WHEN 3 THEN 'Before UPDATE' WHEN 4 THEN 'After UPDATE' WHEN 5 THEN 'MERGE' END Operation, __$update_mask, DID, DName, Manager FROM [cdc].[fn_cdc_get_net_changes_dbo_DepartDemo] (@FromLSN, @ToLSN, 'all with mask')
我们还可以通过转换CDC更新掩码获得更为直观的结果,这里需要借助于另外两个函数sys.fn_cdc_is_bit_set(http://msdn.microsoft.com/zh-cn/library/bb500241%28v=SQL.110%29.aspx)和sys.fn_cdc_get_column_ordinal(http://msdn.microsoft.com/zh-cn/library/bb522549%28v=SQL.100%29.aspx)
/************** 转换CDC更新掩码 *************/ /************* 3w@live.cn 邀月 **************/ UPDATE dbo.[DepartDemo] SET [Manager] = '东方不败' WHERE DID =107 UPDATE dbo.[DepartDemo] SET ParentID = 109 WHERE DID =107 DECLARE @FromLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'smallest greater than or equal' , '2012-04-09 16:09:30') DECLARE @ToLSN varbinary(10) = sys.fn_cdc_map_time_to_lsn ( 'largest less than or equal' , '2012-04-09 23:59:59') SELECT sys.fn_cdc_is_bit_set ( sys.fn_cdc_get_column_ordinal ( 'dbo_DepartDemo' , 'Manager' ), __$update_mask) Manager_Updated, sys.fn_cdc_is_bit_set ( sys.fn_cdc_get_column_ordinal ( 'dbo_DepartDemo' , 'ParentID' ), __$update_mask) ParentID_Updated, DID, Manager, ParentID FROM cdc.fn_cdc_get_all_changes_dbo_DepartDemo (@FromLSN, @ToLSN, 'all') WHERE __$operation = 4
除了前面介绍的指定LSN边界的方法,SQL Server还提供了一系列的获取边界的方法:
sys.fn_cdc_get_max_lsn(http://msdn.microsoft.com/zh-cn/library/bb500304%28v=sql.100%29.aspx)
sys.fn_cdc_get_min_lsn(http://msdn.microsoft.com/zh-cn/library/bb510621%28v=sql.100%29.aspx)
sys.fn_cdc_increment_lsn(http://msdn.microsoft.com/zh-cn/library/bb510745%28v=sql.100%29.aspx)
sys.fn_cdc_decrement_lsn(http://msdn.microsoft.com/zh-cn/library/bb500246%28v=sql.100%29.aspx)
示例如下:
/************** 获取LSN边界的其他方法 *************/ /************* 3w@live.cn 邀月 **************/ --获取最小边界 SELECT sys.fn_cdc_get_min_lsn ('dbo_DepartDemo') Min_LSN --获取可用的最大边界 SELECT sys.fn_cdc_get_max_lsn () Max_LSN --获取最大边界的下一个序号 SELECT sys.fn_cdc_increment_lsn (sys.fn_cdc_get_max_lsn()) New_Lower_Bound_LSN --获取最大边界的前一个序号 SELECT sys.fn_cdc_decrement_lsn (sys.fn_cdc_get_max_lsn()) New_Lower_Bound_Minus_one_LSN
通过以下存储过程在数据库和表级禁用CDC
sys.sp_cdc_disable_table (http://msdn.microsoft.com/zh-cn/library/bb510702(v=sql.100).aspx)
sys.sp_cdc_disable_db(http://msdn.microsoft.com/zh-cn/library/bb522508(v=sql.100).aspx)注意,该命令同时也删除了CDC架构和相关的SQL代理作业。
/************** 在数据库和表级禁用CDC *************/ /************* 3w@live.cn 邀月 **************/ EXEC sys.sp_cdc_disable_table 'dbo', 'DepartDemo', 'all' SELECT is_tracked_by_cdc FROM sys.tables WHERE name = 'DepartDemo' and schema_id = SCHEMA_ID('dbo') --当前数据库上禁用CDC EXEC sys.sp_cdc_disable_db四、使用“更改跟踪”以最小的磁盘开销跟踪净数据更改
CDC 可以用来对数据库和数据仓库的持续数据变更进行异步数据跟踪,而SQL Server 2008中新增的“更改跟踪”却是一个同步进程,是DML操作本身(I/D/U)事务的一部分,它的最大优势是以最小的磁盘开销来侦测净行变更,它允许修改的数据以事务一致的形式表现,并提供了检测数据冲突的能力。它甚至可以根据外部传入的应用程序上下文,来完成更细颗粒度的更改处理,参看WITH CHANGE_TRACKING_CONTEXT (http://msdn.microsoft.com/zh-cn/library/bb895330%28v=sql.100%29.aspx)
/***使用“更改跟踪”以最小的磁盘开销跟踪净数据更改****/ /************* 3w@live.cn 邀月 **************/ IF EXISTS (SELECT [name] FROM sys.databases WHERE name = 'TestDb4') drop DATABASE TestDb4 Go CREATE DATABASE TestDb4 GO --启用更新跟踪,36小时清理一次 ALTER DATABASE TestDb4 SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 36 HOURS, AUTO_CLEANUP = ON)注意下一步是允许快照隔离,这是微软推祟的“最佳实践”,尽管这样行版本的生成会增加额外的空间使用,从而会增加总的I/O数量,但不使用快照会引发事务不一致的变更信息。
ALTER DATABASE TestDb4 SET ALLOW_SNAPSHOT_ISOLATION ON GO SELECT DB_NAME(database_id) 数据库名称,is_auto_cleanup_on, retention_period,retention_period_units_desc FROM sys.change_tracking_databases /* 数据库名称 is_auto_cleanup_on retention_period retention_period_units_desc TestDb4 1 36 HOURS */ USE TestDb4 GO --创建测试表 CREATE TABLE dbo.DepartDemo ([DID] [int] IDENTITY(101,1) NOT NULL PRIMARY KEY, [DName] [nvarchar](200) NULL, [Manager] [nvarchar](50) NULL, [ParentID] [int] NOT NULL DEFAULT ((0)), [CurState] [smallint] NOT NULL DEFAULT ((0)), ) GO ----TRUNCATE table dbo.DepartDemo ----GO --启用表的列更新跟踪 ALTER TABLE dbo.DepartDemo ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = ON) --确认是否更新跟踪开启 SELECT OBJECT_NAME(object_id) ObjNM,is_track_columns_updated_on FROM sys.change_tracking_tables /* ObjNM is_track_columns_updated_on DepartDemo 1 */ --增加测试数据 INSERT dbo.DepartDemo (DName,ParentID) VALUES ('明教', 0), ('五行集', 101), ('少林派',0) SELECT * FROM dbo.DepartDemo --当前版本 SELECT CHANGE_TRACKING_CURRENT_VERSION () as 当前版本 /* 当前版本 1 */ SELECT CHANGE_TRACKING_MIN_VALID_VERSION ( OBJECT_ID('dbo.DepartDemo') )as 最小可用版本 /* 最小可用版本 0 */
函数ChangeTable有两种用法来检测更改: 一、使用Changes关键字 ;二、使用Version关键字
/* 一、使用Changes关键字 */ SELECT DID,SYS_CHANGE_OPERATION, SYS_CHANGE_VERSION FROM CHANGETABLE (CHANGES dbo.DepartDemo, 0) AS CT
UPDATE dbo.DepartDemo SET Manager='张无忌' WHERE DID = 101 UPDATE dbo.DepartDemo SET [DName] = '五行旗' WHERE DID = 102 DELETE dbo.DepartDemo WHERE DID = 103 SELECT CHANGE_TRACKING_CURRENT_VERSION () as 当前版本 /* 当前版本 4 */ --版本1之后的更改 SELECT DID, SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION, SYS_CHANGE_COLUMNS FROM CHANGETABLE (CHANGES dbo.DepartDemo, 1) AS CT
--返回哪些列被修改,1为真,0为假 SELECT DID, CHANGE_TRACKING_IS_COLUMN_IN_MASK( COLUMNPROPERTY( OBJECT_ID('dbo.DepartDemo'),'DName', 'ColumnId') , SYS_CHANGE_COLUMNS) 是否改变DName, CHANGE_TRACKING_IS_COLUMN_IN_MASK( COLUMNPROPERTY( OBJECT_ID('dbo.DepartDemo'), 'Manager', 'ColumnId') , SYS_CHANGE_COLUMNS) 是否改变Manager FROM CHANGETABLE (CHANGES dbo.DepartDemo, 1) AS CT WHERE SYS_CHANGE_OPERATION = 'U' /* DID 是否改变DName 是否改变Manager 101 0 1 102 1 0 */
/* 二、使用Version关键字 */ SELECT d.DID, d.DName, d.Manager, ct.SYS_CHANGE_VERSION FROM dbo.DepartDemo d CROSS APPLY CHANGETABLE (VERSION dbo.DepartDemo , (DID), (d.DID)) as ct
UPDATE dbo.DepartDemo SET DName = '中原明教', CurState = 0 WHERE DID = 101 SELECT d.DID, d.DName, d.Manager, ct.SYS_CHANGE_VERSION FROM dbo.DepartDemo d CROSS APPLY CHANGETABLE (VERSION dbo.DepartDemo , (DID), (d.DID)) as ct
SELECT CHANGE_TRACKING_CURRENT_VERSION () as 当前版本 /* 当前版本 5 */ --跟踪外部程序哪一部分引起的更改,这样好找出源头 DECLARE @context varbinary(128) = CAST('明教内讧引起分裂' as varbinary(128)); WITH CHANGE_TRACKING_CONTEXT (@context) INSERT dbo.DepartDemo (DName, Manager) VALUES ('天鹰教', '殷天正') --查询Context更改 SELECT DID, SYS_CHANGE_OPERATION, SYS_CHANGE_VERSION, CAST(SYS_CHANGE_CONTEXT as varchar) ApplicationContext FROM CHANGETABLE (CHANGES dbo.DepartDemo, 5) AS CT /* DID SYS_CHANGE_OPERATION SYS_CHANGE_VERSION ApplicationContext 104 I 6 明教内讧引起分裂 */
小结:
本文总结了SQL Server中记录数据变更的四个方法:触发器、Output子句、SQL Server 2008中新增的变更数据捕获(CDC)功能、同步更改跟踪。其中后两个是SQL Server 2008中新增的功能,在SQL Server 2012中更是与Always ON紧密集成。
1、不建议前两个。
2、CDC用以实现异步跟踪用户表的数据修改,而且这一功能拥有最小的性能开销,可以用于其他数据源的持续更新,例如将OLTP数据库中的数据变更迁移到数据仓库数据库。
3、”更改跟踪”的最大优势是以最小的磁盘开销来侦测净行变更,它允许修改的数据以事务一致的形式表现,并提供了检测数据冲突的能力。
其他推荐文章:
1、在VS中如何将数据同步配置为使用 SQL Server 更改跟踪(http://msdn.microsoft.com/zh-cn/library/cc714038.aspx)
2、SQL Server 2012中复制、更改跟踪、更改数据捕获和 AlwaysOn 可用性组 (SQL Server)(http://msdn.microsoft.com/zh-cn/library/hh403414%28v=sql.110%29.aspx)
助人等于自助! 3w@live.cn
相关推荐
SQL Server 2008 的更改数据捕获:崭新的异步 CDC 解决方案能够提高性能 SQL Server 2008 的更改数据捕获(CDC)是一种崭新的异步解决方案,可以提高性能。CDC 是 SQL Server 2008 关系型数据库引擎的一个内置功能...
自从SQLServer2008引入了数据变更捕获功能(后面简称为CDC)后,解决了很多烦恼问题,如客户2个月前更改了一个数据,但是由于服务器空间不足,经常只能保留一个月的备份。此时客户为了逃避因为更改数据带来的较大...
CDC(Change Data Capture)是一种技术,用于跟踪和捕获数据库中的数据变更。它分为两大类:基于查询的CDC,如DataX和Kettle,它们通过定期查询来获取变化;以及基于日志的CDC,如Debezium、Canal和Flink-CDC,后者...
在SQL Server 2008中,Change Data Capture (CDC) 是一项强大的功能,用于记录数据库表中的数据变更。此功能对于数据审计、数据仓库同步和业务流程监控等场景非常有用。本文将深入探讨如何使用SQL Server 2008的CDC...
SQL Server 2008 Native Client是微软推出的一款用于与SQL Server进行数据交互的客户端库,它是SQL Server数据库引擎和应用程序之间的一个接口。这个库包含了ODBC(Open Database Connectivity)驱动程序和OLE DB...
SQL Server 2008是微软推出的一款关系型数据库管理系统,它在企业级数据管理和分析领域扮演着重要的角色。此安装包提供了64位和32位两种版本,以适应不同硬件环境的需求。以下是关于SQL Server 2008的一些核心知识点...
Sql Server 2005 打开 Sql Server 2008 mdf 文件数据库转换是指将 Sql Server 2008 中的数据库文件(mdf 文件)转换为 Sql Server 2005 可以识别的格式,以便在 Sql Server 2005 中使用。这种转换过程需要使用 Sql ...
- **事务处理**:阐述了事务的基本概念及其在SQL Server中的实现方式,包括如何使用BEGIN TRANSACTION、COMMIT和ROLLBACK语句来确保数据的一致性和完整性。 #### 四、性能优化与最佳实践 为了帮助读者更好地利用...
Microsoft sql server 2008 Native Client (SQL Server Native Client) 是一个同时包含 SQL OLE DB 访问接口和 SQL ODBC 驱动程序的动态链接库 (DLL)。它对使用本机代码 API(ODBC、OLE DB 和 ADO)连接 Microsoft ...
SQL SERVER 2008 是一个功能强大且集成的数据解决方案,提供了一个安全、可靠、HIGH效的平台用于企业数据和商业智能应用。.NET Framework 是 SQL SERVER 2008 的核心组件之一,提供了一个一致的面向对象的编程环境,...
SQL Server 2008是一款由Microsoft开发的关系型数据库管理系统,广泛应用于企业级的数据存储、管理和分析。在日常运维工作中,有时需要卸载并重新安装SQL Server 2008来解决各种问题或升级到更高版本。传统的卸载...
在使用SQL Server 2008的过程中,部分用户遇到了一个比较棘手的问题:当尝试修改数据表中的字段或类型时,系统不允许保存这些更改。这一问题通常发生在重装SQL Server 2008之后,表现为在设计视图中编辑表结构时,...
SQL Server 2008 R2 主从数据库同步是高可用性技术之一,通过配置数据库属性和事务日志传送,实现主从数据库之间的数据同步。本文将详细介绍 SQL Server 2008 R2 主从数据库同步的配置步骤和实现原理。 基本原理 ...
SQL Server 2008 JDBC驱动还支持一些高级特性,如读写分离、分布式事务、大数据类型处理(如XML和二进制数据)、JDBC批处理以及SQL Server特有的功能(如Service Broker或Integration Services)。 9. **错误处理*...
利用 Microsoft SQL Server 2008 Office 2007 数据挖掘外接程序,您可以在 Office Excel 2007 和 Office Visio 2007 中利用 SQL Server 2008 的预测分析功能。此下载文件包括以下组件: Excel 表分析工具:此外接...
在 SQL Server 2008 中,修改视图是通过使用 Alter View 语句来实现的。下面将详细介绍修改视图的语法、实例和注意事项。 修改视图语法 修改视图的基本语法格式为: Alter View <视图名> [<列名>[, …]] As 语句>...
总的来说,SQL Server 2008驱动包是连接应用程序和数据库的桥梁,它确保了不同编程环境下的数据交互能力,是开发和管理SQL Server 2008应用程序不可或缺的一部分。通过理解这些驱动的特性和用途,开发者可以更有效地...
SQL Server 2005/2008 Express Profiler 是微软SQL Server数据库管理系统中一个强大的性能监视工具,尤其适用于SQL Server 2008 Express版本。它允许开发者和DBA(数据库管理员)深入地洞察数据库系统的运行情况,...
SSIS是一个ETL(提取、转换、加载)工具,用于整合来自不同来源的数据,并将其加载到SQL Server中。通过图形化的设计界面,用户可以创建数据流任务,进行数据清洗、转换和加载,支持大规模数据迁移和数据仓库建设。 ...