0

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

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函数,但它很容易发生冲突,有时可能会错过更改。但是我喜欢我可以制作一个临时表并使用的方式CHECKSUM(*),这使得维护更容易(不必在查询和 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;

我知道HASHBYTES函数(它支持 sha1、md5,它们不太容易发生冲突),但它只接受 varchar 或 varbinary,而不接受列列表或 * CHECKSUM 的方式。必须从查询中转换/转换每一列是一个痛苦......并且打开了错误的大门(例如忘记包含一个新字段)

我还注意到SQL Server 的变更数据捕获和变更跟踪功能,但对于我正在做的事情来说,它们似乎都很复杂和矫枉过正。

所以我的问题:是否有其他方法可以从满足我的条件的查询或临时表中生成散列?

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

4

1 回答 1

1

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;
于 2013-11-12T19:06:49.943 回答