احصل على تجزئة خالية من الاصطدام لاستعلام محدد أو طريقة عرض مع SQL Server 2008

StackOverflow https://stackoverflow.com/questions/19841786

سؤال

أنا أعمل في مشروع أحتاج إلى مزامنة البيانات من نظامنا إلى نظام خارجي. ما أريد تحقيقه ، هو إرسال العناصر التي تم تغييرها بشكل دوري بشكل دوري من استعلام مخصص. يبدو هذا الاستعلام مثل هذا (ولكن مع العديد من الأعمدة):

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;

أنا على علم hashbytes الوظيفة (التي تدعم 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