Sql server 检测SQL Server 2000表数据中的更改
我定期检查某个查询(顺便说一句,该查询包含多个表),以便在上次检查后(每天一次)发生更改时向用户添加信息性消息 我尝试使用Sql server 检测SQL Server 2000表数据中的更改,sql-server,hash,sql-server-2000,checksum,Sql Server,Hash,Sql Server 2000,Checksum,我定期检查某个查询(顺便说一句,该查询包含多个表),以便在上次检查后(每天一次)发生更改时向用户添加信息性消息 我尝试使用校验和+agg(binary\u checksum(*),但它没有帮助,所以帮助不大,因为我有以下情况(过于简化): 及 上述两种情况都会导致相同的校验和49,很明显数据已经更改 这不一定是一个简单的函数或简单的解决方案,但我需要某种方法来唯一识别SQL server 2000中的差异。校验和\u agg似乎只是将所有行的二进制校验和结果相加。尽管每一行都发生了变化,但两个校
校验和+agg(binary\u checksum(*)
,但它没有帮助,所以帮助不大,因为我有以下情况(过于简化):
及
上述两种情况都会导致相同的校验和49,很明显数据已经更改
这不一定是一个简单的函数或简单的解决方案,但我需要某种方法来唯一识别SQL server 2000中的差异。校验和\u agg似乎只是将所有行的二进制校验和结果相加。尽管每一行都发生了变化,但两个校验和之和没有变化(即17+32=16+33)。这并不是检查更新的标准,但我可以提出以下建议:
checksum\u agg
,而是将校验和串接成一个分隔字符串,并按照从MyTable FOR XML PATH(“”)中选择binary\u checksum(*)+“,”的行比较字符串。要检查和存储的字符串要长得多,但进行误报比较的可能性要小得多
-- Create the test table and populate it
CREATE TABLE #Test (
f1 INT,
f2 INT
)
INSERT INTO #Test VALUES(1, 1)
INSERT INTO #Test VALUES(2, 0)
INSERT INTO #Test VALUES(2, 1)
/*******************
OPTION 1
*******************/
SELECT CAST(binary_checksum(*) AS VARCHAR) + ',' FROM #test FOR XML PATH('')
-- Declaration: Input and output MD5 checksums (@in and @out), input string (@input), and counter (@i)
DECLARE @in VARBINARY(16), @out VARBINARY(16), @input VARCHAR(MAX), @i INT
-- Initialize @input string as the XML dump of the table
-- Use this as your comparison string if you choose to not use the MD5 checksum
SET @input = (SELECT * FROM #Test FOR XML RAW)
/*******************
OPTION 3
*******************/
SELECT @input
-- Initialise counter and output MD5.
SET @i = 1
SET @out = 0x00000000000000000000000000000000
WHILE @i <= LEN(@input)
BEGIN
-- calculate MD5 for this batch
SET @in = HASHBYTES('MD5', SUBSTRING(@input, @i, CASE WHEN LEN(@input) - @i > 8000 THEN 8000 ELSE LEN(@input) - @i END))
-- xor the results with the output
SET @out = CAST(CAST(SUBSTRING(@in, 1, 4) AS INT) ^ CAST(SUBSTRING(@out, 1, 4) AS INT) AS VARBINARY(4)) +
CAST(CAST(SUBSTRING(@in, 5, 4) AS INT) ^ CAST(SUBSTRING(@out, 5, 4) AS INT) AS VARBINARY(4)) +
CAST(CAST(SUBSTRING(@in, 9, 4) AS INT) ^ CAST(SUBSTRING(@out, 9, 4) AS INT) AS VARBINARY(4)) +
CAST(CAST(SUBSTRING(@in, 13, 4) AS INT) ^ CAST(SUBSTRING(@out, 13, 4) AS INT) AS VARBINARY(4))
SET @i = @i + 8000
END
/*******************
OPTION 2
*******************/
SELECT @out
——创建测试表并填充它
创建表#测试(
f1 INT,
f2 INT
)
插入#测试值(1,1)
插入#测试值(2,0)
插入#测试值(2,1)
/*******************
选择1
*******************/
从#XML路径测试(“”)中选择CAST(二进制校验和(*)作为VARCHAR)+’,'
--声明:输入和输出MD5校验和(@in和@out)、输入字符串(@Input)和计数器(@i)
声明@in-VARBINARY(16),@out-VARBINARY(16),@input-VARCHAR(MAX),@i-INT
--将@input字符串初始化为表的XML转储
--如果选择不使用MD5校验和,请将其用作比较字符串
设置@input=(从#测试XML原始数据中选择*
/*******************
选择3
*******************/
选择@input
--初始化计数器并输出MD5。
设置@i=1
设置@out=0x00000000000000
而@i 8000然后8000 ELSE LEN(@input)-@i END))
--将结果与输出进行异或运算
设置@out=CAST(CAST(子字符串(@in,1,4)为INT)^CAST(子字符串(@out,1,4)为INT)为VARBINARY(4))+
转换(转换(子字符串(@in,5,4)为INT)转换(子字符串(@out,5,4)为INT)为VARBINARY(4))+
强制转换(子字符串(@in,9,4)为INT)强制转换(子字符串(@out,9,4)为INT)为VARBINARY(4))+
强制转换(子字符串(@in,13,4)为INT)强制转换(子字符串(@out,13,4)为INT)为VARBINARY(4))
设置@i=@i+8000
结束
/*******************
选择2
*******************/
选择@out
相关问题:尝试将时间戳
/行版本
列添加到基表中。不幸的是,“hashbytes”在SQL Server 2000中不是可识别的函数名。aah SQL2000。我错过了那个!我在这里找到了T-SQL的MD实现:。为疏忽道歉。我不相信有人真的写了这篇文章,感谢脚本和解决方案。请所有阅读此问题的人注意:我将问题查询中的checksum\u agg(binary\u checksum(*)替换为checksum\u agg(binary\u checksum(dbo.MD5)(cast(checksum(*)as nvarchar(4000‘‘)'))
这实际上可以解决我的问题。。。
select checksum_agg(binary_checksum(*))
from
(
select 1 as id,
0 as status
union all
select 2 as id,
1 as status
) data
-- Create the test table and populate it
CREATE TABLE #Test (
f1 INT,
f2 INT
)
INSERT INTO #Test VALUES(1, 1)
INSERT INTO #Test VALUES(2, 0)
INSERT INTO #Test VALUES(2, 1)
/*******************
OPTION 1
*******************/
SELECT CAST(binary_checksum(*) AS VARCHAR) + ',' FROM #test FOR XML PATH('')
-- Declaration: Input and output MD5 checksums (@in and @out), input string (@input), and counter (@i)
DECLARE @in VARBINARY(16), @out VARBINARY(16), @input VARCHAR(MAX), @i INT
-- Initialize @input string as the XML dump of the table
-- Use this as your comparison string if you choose to not use the MD5 checksum
SET @input = (SELECT * FROM #Test FOR XML RAW)
/*******************
OPTION 3
*******************/
SELECT @input
-- Initialise counter and output MD5.
SET @i = 1
SET @out = 0x00000000000000000000000000000000
WHILE @i <= LEN(@input)
BEGIN
-- calculate MD5 for this batch
SET @in = HASHBYTES('MD5', SUBSTRING(@input, @i, CASE WHEN LEN(@input) - @i > 8000 THEN 8000 ELSE LEN(@input) - @i END))
-- xor the results with the output
SET @out = CAST(CAST(SUBSTRING(@in, 1, 4) AS INT) ^ CAST(SUBSTRING(@out, 1, 4) AS INT) AS VARBINARY(4)) +
CAST(CAST(SUBSTRING(@in, 5, 4) AS INT) ^ CAST(SUBSTRING(@out, 5, 4) AS INT) AS VARBINARY(4)) +
CAST(CAST(SUBSTRING(@in, 9, 4) AS INT) ^ CAST(SUBSTRING(@out, 9, 4) AS INT) AS VARBINARY(4)) +
CAST(CAST(SUBSTRING(@in, 13, 4) AS INT) ^ CAST(SUBSTRING(@out, 13, 4) AS INT) AS VARBINARY(4))
SET @i = @i + 8000
END
/*******************
OPTION 2
*******************/
SELECT @out