网络编程
位置:首页>> 网络编程>> 数据库>> SQL点滴24 监测表的变化

SQL点滴24 监测表的变化

 来源:asp之家 发布时间:2011-09-30 11:38:41 

标签:监测表,sql

有时候,我们在某一重要的时间段需要监控某张表的变化情况,包含插入、更新、删除。举例来说,当我们把数据导出到外部的系统时,我们希望导出的是全部的数据,而且最好是导出上次导出之后变动的数据。
作为DBA,我们可采传统的触发器操作,来构建一个元数据表或一个时间戳列来监控数据的变化。
代码如下:Code Listing 1
该代码在 SQL 2005(SP3), SQL 2008 R2 (RTM with cu5)测试通过 

代码如下:


-------------------
--Method 1: TRIGGER
-------------------
--Base Table Definition
IF OBJECT_ID('CheckSumTest', 'U') IS NOT NULL DROP TABLE CheckSumTest
GO
CREATE TABLE CheckSumTest
(
id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
vc1 varchar(1) NOT NULL,
vc2 varchar(1) NOT NULL
)
GO
INSERT dbo.CheckSumTest (vc1, vc2) SELECT 'a', 'b'
INSERT dbo.CheckSumTest (vc1, vc2) SELECT 'b', 'a'
GO
--Create Audit Summary Table to hold Meta-Data
IF OBJECT_ID('dbo.TableAuditSummary', 'U') IS NOT NULL DROP TABLE dbo.TableAuditSummary
CREATE TABLE dbo.TableAuditSummary
( id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
TableName sysname NOT NULL,
LastUpdate DATETIME NOT NULL,
LastExport DATETIME NOT NULL
)
GO
INSERT dbo.TableAuditSummary (TableName, LastUpdate, LastExport) VALUES ('dbo.CheckSumTest', GETDATE(), GETDATE())
GO
--Tables that need exporting
SELECT * FROM dbo.TableAuditSummary WHERE LastUpdate>LastExport
--Create Trigger on all Base Tables
--This fires on any insert/update/delete and writes new LastUpdate column for the table set to Current Date and Time
IF OBJECT_ID('dbo.trg_CheckSumTest_MaintainAuditSummary', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_CheckSumTest_MaintainAuditSummary
GO
CREATE TRIGGER dbo.trg_CheckSumTest_MaintainAuditSummary
ON dbo.CheckSumTest
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
IF (object_id('dbo.CheckSumTest') IS NOT NULL)
UPDATE dbo.TableAuditSummary SET LastUpdate=GETDATE() WHERE TableName='dbo.CheckSumTest'
END
GO
--Make an Update
UPDATE dbo.CheckSumTest SET vc1='b', vc2='a' WHERE id=1
UPDATE dbo.CheckSumTest SET vc1='a', vc2='b' WHERE id=2
--Check Meta-Data
SELECT * FROM dbo.TableAuditSummary WHERE LastUpdate>LastExport
--When we have Exported the data, we run the following to reset MetaData
UPDATE dbo.TableAuditSummary SET LastExport=GETDATE() WHERE LastUpdate>LastExport


最近我正在读关天SQLSERVER在线帮助(BOL)相关的知识, 我接触到了 SQL Server CHECKSUM(), BINARY_CHECKSUM(), and CHECKSUM_AGG() 这几个函数, 由此突然想到这些函数是不是也可以监控表的数据变化,而事实证明CHECKSUM_AGG() 函数尽管被描述为检测表的变化,但这里不适用.
使用 CheckSum() and CheckSum_Agg() 函数
CHECKSUM_AGG() 函数, 在Books OnLine 和许多相关的站点上是这样描述的, 通常用于检测一个表的数据是否更改. 这是一个代替触发器的更好的方法,只是该操作会引起表扫描的操作。于是我这次我仍然使用元数据来跟踪数据的变化,只是新建了列LastChkSum代替了LastUpdate,该列用于保存CHECKSUM_AGG(BINARY_CHECKSUM(*)),它将会在全表中产生一个唯一值,以区别数据的变化情况。
代码如下: Listing 2. 

代码如下:


---------------------------------------------
--Method 2 : using CheckSum (not reliable)
---------------------------------------------
--Base Table Definition
IF OBJECT_ID('CheckSumTest', 'U') IS NOT NULL DROP TABLE CheckSumTest
GO
CREATE TABLE CheckSumTest
(
id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
vc1 varchar(1) NOT NULL,
vc2 varchar(1) NOT NULL
)
GO
INSERT dbo.CheckSumTest (vc1, vc2) SELECT 'a', 'b'
INSERT dbo.CheckSumTest (vc1, vc2) SELECT 'b', 'a'
GO
--Create Audit Summary Table to hold Meta-Data
IF OBJECT_ID('dbo.TableAuditSummary', 'U') IS NOT NULL DROP TABLE dbo.TableAuditSummary
CREATE TABLE dbo.TableAuditSummary
( id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
TableName sysname NOT NULL,
LastChkSum INT NOT NULL
)
GO
INSERT dbo.TableAuditSummary (TableName, LastChkSum)
SELECT 'dbo.CheckSumTest', CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM dbo.CheckSumTest
GO
--Tables that need exporting
SELECT * FROM dbo.TableAuditSummary WHERE TableName='dbo.CheckSumTest'
AND LastChkSum<>(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM dbo.CheckSumTest)
UNION ALL
...
--Make a Simple (Single row) Update
UPDATE dbo.CheckSumTest SET vc1='c', vc2='a' WHERE id=1
--Tables that need exporting
SELECT * FROM dbo.TableAuditSummary WHERE TableName='dbo.CheckSumTest'
AND LastChkSum<>(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM dbo.CheckSumTest)
UNION ALL
...
--Reset MetaData
UPDATE dbo.TableAuditSummary SET LastChkSum=(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM dbo.CheckSumTest)
WHERE TableName='dbo.CheckSumTest'
--Make a Symmetric change
UPDATE dbo.CheckSumTest SET vc1='b', vc2='a' WHERE id=1
UPDATE dbo.CheckSumTest SET vc1='c', vc2='a' WHERE id=2
--Tables that need exporting (no rows returned as CHECKSUM_AGG() has not changed!!)
SELECT * FROM dbo.TableAuditSummary WHERE TableName='dbo.CheckSumTest'
AND LastChkSum<>(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM dbo.CheckSumTest)
UNION ALLCode Listing 2


正如你所看到的那样,对于单个的变化的情况,CHECKSUM是使用比较好的,但是CHECKSUM_AGG()却不能反应数据的变化
代码如下:Code Listing 3

代码如下:


--Base Table Definition
IF OBJECT_ID('CheckSumTest', 'U') IS NOT NULL DROP TABLE CheckSumTest
GO
CREATE TABLE CheckSumTest
(
id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
vc1 varchar(1) NOT NULL,
vc2 varchar(1) NOT NULL,
chksum1 AS (CHECKSUM(id, vc1, vc2)),
chksum2 AS (BINARY_CHECKSUM(id, vc1, vc2))
)
GO
INSERT dbo.CheckSumTest (vc1, vc2) SELECT 'a', 'b'
INSERT dbo.CheckSumTest (vc1, vc2) SELECT 'b', 'a'
GO
--Show Computed Columns and CheckSum_Agg() value = 199555
SELECT * FROM CheckSumTest
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM CheckSumTest
--Make a Simple (Single row) Update
UPDATE dbo.CheckSumTest SET vc1='c', vc2='a' WHERE id=1
--Show Computed Columns and CheckSum_Agg() value = 204816 (Ok)
SELECT * FROM CheckSumTest
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM CheckSumTest
--Make a Symmetric change
UPDATE dbo.CheckSumTest SET vc1='b', vc2='a' WHERE id=1
UPDATE dbo.CheckSumTest SET vc1='c', vc2='a' WHERE id=2
--Show Computed Columns and CheckSum_Agg() value = 204816 (Not Ok!)
SELECT * FROM CheckSumTest
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM CheckSumTest


我们会发现调整前后 CHECKSUM_AGG(BINARY_CHECKSUM(*)) 的值是一样的,不能区分
结论:
CHECKSUM_AGG() 函数尽管被描述为能监测表数据的变化,在实际测试中是不行的。尤其是对表进行对称数据修改时,无法监测
作者:Tyler Ning

0
投稿

猜你喜欢

  • SQL Server有两种备份方式,一种是使用BACKUP DATABASE将数据库文件备份出去,另外一种就是直接拷贝数据库文件mdf和日志
  • &ldquo;你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起
  • 任何熟悉SQL和关系数据库的人都遇见过大量的连接类型。最简单的说,连接(join)会把两个表的内容组合到一个虚拟表或者recordset内。
  • 也许还有朋友不太清楚DOMContentLoaded这个事件。简单的说,这个事件就是要在大多数情况下去替代window.onload事件,因
  • 目前网络数据库的应用已经成为最为广泛的应用之一了,并且关于数据库的安全性,性能都是企业最为关心的事情。数据库渐渐成为企业的命脉,优化查询就解
  • 说明:本函数作用是截取指定英汉混合字符串,并保持显示长度一至。就是将一个汉字当两英文来截取。用途:一般会用在标题显示列表,可以避免截取的字符
  • InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句
  • 函数名:chk_Email()'返回值:布尔值(True为通过,False为未通过)'参数:email(需要判断的email
  • 我们可用正规表达式来寻找并替换URL和邮件地址为活动的超级链接。用到的主要函数就是InsertHyperlinks(inText),语法为:
  • 只是做笔记,没什么!!  代码如下:--创建测试表 CREATE TABLE [dbo].[Student]( [ID] [int
  • 如IP为192.168.1.111现要截取第二个.之前的值,得到结果192.168,很多网站都只显示前面2个值  &nb
  • 原文:10 Principles Of Effective Web Design翻译:熊猫2008-02-03本文由熊猫同学授权翻译首发。并
  • SQL语句先前写的时候,很容易把一些特殊的用法忘记,我特此整理了一下SQL语句操作,方便自己写SQL时方便一点,想贴上来,一起看看,同时希望
  • CSS 和 JavaScript 的压缩已经很成熟,各大网站都在使用。HTML 的压缩(特指去除空白字符和注释),除了 Google 等搜索
  • MySQL默认编码是latin1,因业务需要把它转到UTF8。1、导出数据导出表结构 mysqldump -d dataname >
  • 在web2.0的站中用户互动性是很强的,例如用户留言我们可能放开img标签,允许用户外链其他站点的图片,那么我们就需要解决图片尺寸过大所带来
  • 在广大网友心目中,他们就是中国互联网搜索领域的三驾马车。无论这三家搜索巨头承不承认,在网友眼中总会来将他们进行对比比较。当然,更多时候的比较
  • SQL Server 2000 清理日志精品教程SQL Server 2000 数据库日志太大!如何清理SQL Server 2000的日志
  • 1:下载FCKEditor编辑器下载下来后解压到你网站的目录,最好就放在根目录下,文件夹名字就用FCKEditor;这里可以随便自己喜好,但
  • 说到 IE 的 bug,一个臭名昭著的例子是它对于“盒模型”的错误解释:在 IE5.x 以及 Quirks 模式的 IE6/7 中,将 bo
手机版 网络编程 asp之家 www.aspxhome.com