Domanda

Sto lavorando a un progetto in cui ho bisogno di sincronizzare i dati dal nostro sistema a un sistema esterno. Quello che voglio ottenere è inviare periodicamente solo articoli modificati (righe) da una query personalizzata. Questa query sembra questo (ma con molte altre colonne):

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

Voglio evitare di dover confrontare ogni campo uno a uno tra le sincronizzazioni. Sono venuto con l'idea di poter generare un hash per ogni riga della mia query e confrontarlo con l'hash dalla sincronizzazione precedente, che restituirà solo le righe modificate. Sono a conoscenza del Checksum funzione, ma è molto soggetta a collisioni e potrebbe perdere cambiamenti a volte. Tuttavia mi piace il modo in cui potrei semplicemente fare una tabella di temperatura e usare CHECKSUM(*), che semplifica la manutenzione (non dover aggiungere campi nella query e nel 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;

Sono a conoscenza Hashbytes funzione (che supporta sha1, md5, che sono meno inclini alle collisioni), ma accetta solo varchar o varbinary, non un elenco di colonne o * il modo in cui il checksum. Dover lanciare/convertire ogni colonna dalla query è un dolore al ... e apre la porta agli errori (dimentica di includere un nuovo campo per esempio)

Ho anche notato Modificare l'acquisizione dei dati e il monitoraggio di modifica Funzionalità di SQL Server, ma sembrano tutte complicate e eccessive per quello che sto facendo.

Quindi la mia domanda: esiste un altro metodo per generare un hash da una query o da una tabella di temperatura che soddisfa i miei criteri?

In caso contrario, c'è un altro modo per ottenere questo tipo di lavoro (per sincronizzare le differenze da una query)

È stato utile?

Soluzione

Ho trovato un modo per fare esattamente quello che volevo, grazie al FOR XML Clausola:

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top