私は、システムから外部システムにデータを同期する必要があるプロジェクトに取り組んでいます。私が達成したいのは、カスタムクエリから変更されたアイテム (行) のみを定期的に送信することです。このクエリは次のようになります (ただし、さらに多くの列があります)。
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
同期間ですべてのフィールドを 1 対 1 で比較する必要はありません。クエリからすべての行のハッシュを生成し、これを以前の同期からのハッシュと比較すると、変更された行のみが返されるという考えに至りました。私は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 をサポート) は知っていますが、列のリストや CHECKSUM のように * ではなく、varchar または varbinary のみを受け入れます。クエリからすべての列をキャスト/変換する必要があるのは面倒です...そしてエラーへの扉を開きます(たとえば、新しいフィールドを含めるのを忘れます)
また、SQL Server の変更データ キャプチャ機能と変更追跡機能にも気付きましたが、それらはすべて複雑で、私がやっていることにはやり過ぎのように思えます。
だから私の質問:私の基準を満たすクエリまたは一時テーブルからハッシュを生成する他の方法はありますか?
そうでない場合、この種の作業を達成する別の方法はありますか (クエリとの違いを同期するため)