设为首页 收藏本站
查看: 2489|回复: 0

[经验分享] SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

[复制链接]

尚未签到

发表于 2015-6-27 16:08:03 | 显示全部楼层 |阅读模式
  CDC(Change Data Capture:变更数据捕获)这个功能是SQL Server 2008企业版的功能,它提供了一种新的机制,对表格数据的更新进行跟踪,在数据仓库的建设过程中,通过这种技术,可以简化从业务数据库导入数据的复杂度。
  
  之前我有过两篇文章介绍,最近因为又在和有关客户介绍这方面的应用。发现之前的例子不是那么完整和清楚,特此再整理一篇出来,给大家参考
  


  •   SQL Server 2008 的CDC功能

  •   关于CDC功能的答疑
  
1. 准备一个数据库,里面准备一个表,Orders
DSC0000.png
2. 启用数据库级别的CDC选项
--在数据库级别启用CDC功能
EXEC sys.sp_cdc_enable_db
  这个命令执行完之后,会在系统表里面添加6个表格
DSC0001.png
  

3.在需要做数据捕获的表上面启用CDC选项
EXEC sys.sp_cdc_enable_table @source_schema='dbo',@source_name='Orders',@capture_instance='Orders',@supports_net_changes=0,@role_name=null
  
  【备注】关于这个存储过程的具体用法和有关参数的含义,请参考

  http://msdn.microsoft.com/en-us/library/bb522475.aspx
  
  执行之后,会有如下的输出消息
DSC0002.png
  这个提示的意思是说,要启动SQL Server Agent。因为CDC功能是要通过一个两个作业来自动化完成的
DSC0003.png
  
  与此同时,执行上面的命令还将在系统表中添加一个表格
DSC0004.png
  
  还会添加一个函数
DSC0005.png
  

4.插入或者更新数据测试CDC功能
--插入或者更新数据测试CDC功能
INSERT Orders(CustomerID) VALUES('Microsoft');
INSERT Orders(CustomerID) VALUES('Google');
UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
DELETE FROM Orders WHERE OrderID=2
  这个范例插入两行数据,紧接着又对第一行更新,然后还删除了第二行,所以最终只有一行数据
DSC0006.png

  那么,我们来看看CDC做了什么事情呢?
SELECT * FROM cdc.Orders_CT
DSC0007.png
  我们可以来解释一下上面结果的含义
  __$operation=2的情况,表示新增
  __$operation=3或者4,表示更新,3表示旧值,4表示新值
  __$operation=1的情况,表示删除
  
  很好理解,不是吗?
  但是,我们一般都是需要按照时间范围进行检索,对吧,所以,需要使用下面的语法进行查询
--按照时间范围查询CDC结果
DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
  
  关于sys.fn_cdc_map_time_to_lsn这个函数,请参考
  http://msdn.microsoft.com/en-us/library/bb500137.aspx

  查询的结果如下
DSC0008.png

  
  如果需要包含更新操作的旧值,则可以以下的语法
DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all update old')
  

DSC0009.png
  
  通常,为了方便起见,我们会将这个查询定义为一个存储过程,如下
--定义存储过程来进行查询
CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
AS
BEGIN
DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
END
  

  然后,每次需要用的时候,就直接调用即可
--执行存储过程
EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'
  


5.结合SSIS实现事实表的增量更新
  下面展示了一个SSIS 包的设计,这里面读取CDC的数据,先进行一些查找,然后按照__$operation的值拆分成为三个操作,分别进行插入,更新和删除,这样就可以实现对事实表的增量更新
DSC00010.png
  
  
  本文所有的代码如下
USE SampleDatabase
GO
--在数据库级别启用CDC功能
EXEC sys.sp_cdc_enable_db
--在需要做数据捕获的表格上面启用CDC功能
EXEC sys.sp_cdc_enable_table @source_schema='dbo',@source_name='Orders',@capture_instance='Orders',@supports_net_changes=0,@role_name=null
--插入或者更新数据测试CDC功能
INSERT Orders(CustomerID) VALUES('Microsoft');
INSERT Orders(CustomerID) VALUES('Google');
UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
DELETE FROM Orders WHERE OrderID=2
--查询CDC的结果
SELECT * FROM cdc.Orders_CT

--按照时间范围查询CDC结果
DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
--定义存储过程来进行查询
CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
AS
BEGIN
DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
END
--执行存储过程
EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-80989-1-1.html 上篇帖子: 【翻译】SQL Server索引进阶:第一级,索引简介 下篇帖子: SQL Server 全文索引的硬伤
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表