我正在研究一个项目,我需要将系统从系统同步到外部系统。我要实现的目标是定期从自定义查询发送更改的项目(行)。此查询看起来像这样(但还有更多列):

SELECT T1.field1,
    T1.field2,
    T1.field2,
    T1.field3,
    CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
    T2.field1,
    T3.field1,
    T4.field1
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk

我想避免在同步之间比较每个字段。我提出了这样的想法,即可以从查询中为每一行生成一个哈希,并将其与以前的同步的哈希进行比较,这将仅返回更改的行。我知道 校验和 功能,但它非常容易碰撞,有时可能会错过更改。但是我喜欢我可以做一个临时表并使用的方式 CHECKSUM(*), ,这使维护更容易(不必在查询和校验和中添加字段):

SELECT T1.field1,
    T1.field2,
    T1.field2,
    T1.field3,
    CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
    T2.field1,
    T3.field1,
    T4.field1
INTO #tmp
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk;

-- get all columns from the query, plus a hash of the row
SELECT *, CHECKSUM(*)
FROM #tmp;

我知道 哈希比 函数(支持SHA1,MD5,不太容易碰撞),但它仅接受Varchar或Varbinary,而不接受列列表或 * checksum的方式。不得不从查询中施放/转换每一列是一个痛苦的...

我也注意到 更改数据捕获和更改跟踪 SQL Server的功能,但它们似乎都很复杂,而且对我的工作都过高。

因此,我的问题是:是否有其他方法从符合我的标准的查询或临时表中生成哈希?

如果没有,是否有其他方法可以实现此类工作(与查询同步差异)

有帮助吗?

解决方案

我找到了做我想要的准确的方法,这要归功于 FOR XML 条款:

SELECT T1.field1,
    T1.field2,
    T1.field2,
    T1.field3,
    CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
    T2.field1,
    T3.field1,
    T4.field1
INTO #tmp
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk;

-- get all columns from the query, plus a hash of the row (converted in an hex string)
SELECT T.*, CONVERT(VARCHAR(100), HASHBYTES('sha1', (SELECT T.* FOR XML RAW)), 2) AS sHash
FROM #tmp AS T;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top