Articles

Redgate Hub

Introduzione

Ci sono diversi motivi per cui potrebbe essere necessario confrontare tabelle o risultati.

  • A volte, basta sapere se le tabelle contengono dati uguali o diversi; Nessun dettaglio: solo sì o no. Questo è tipico delle asserzioni di test, in cui è sufficiente sapere se la routine o il batch producono un risultato con i dati giusti al suo interno. quando fornito con vales particolari per i parametri. È sbagliato o giusto
  • Occasionalmente, è necessario sapere quali righe sono cambiate senza, forse, essere particolari su quali colonne sono cambiate e come.
  • Ci sono momenti in cui hai una tabella di grandi dimensioni in termini di colonne e righe e hai bisogno di qualcosa che ti mostri specificamente le colonne che hanno cambiato il loro valore. Potresti anche volerlo quando rintracci un bug in una routine che potrebbe altrimenti richiedere di perdere tempo a scansionare “a occhio”.

Affronteremo questi tre compiti piuttosto diversi in SQL

Se due tabelle hanno un numero diverso di righe, ovviamente non possono essere le stesse. Tuttavia, ci sono momenti in cui è necessario sapere se Table_B contiene tutte le righe di Table_A, senza differenze. Se desideri maggiori dettagli, potresti anche voler conoscere le righe in una tabella che non sono in comune o le righe comuni, come indicato dalla chiave primaria, che erano diverse. Perché limitarsi a confrontare solo due tabelle? Ci sono modi per confrontare quanti ne hai bisogno. (come, ad esempio, quando si confrontano i metadati in diverse istantanee del database). Sì, ci sono molte varianti

Hai strumenti e funzionalità per fare questa roba, sicuramente?

C’è sempre un posto per strumenti come SQL Data Compare, TableDiff, tSQLt o Change Data Capture. Molto dipende dalle circostanze e dal tipo di attività. Il problema di fare audit sulle modifiche ai dati in un sistema live è un argomento separato, così come la sincronizzazione di tabelle e database. Confronto di documenti XML sono anche fuori portata. Ci occuperemo esclusivamente del confronto di routine dei dati nelle tabelle

È più probabile che utilizzi le tecniche TSQL per confrontare le tabelle quando:

Sviluppo…

Nel corso dello sviluppo di un database, molte tabelle vengono confrontate. Non è solo la roba grande: ogni funzione con valore di tabella, ad esempio, ha bisogno di un cablaggio di prova nello script di build che si assicuri che faccia ciò che si pensa che dovrebbe fare in tutte le circostanze di test immaginabili e che incorpora tutti i casi limite in cui è stato catturato dai tester in passato. Ogni stored procedure richiede un test per assicurarsi che il processo che esegue faccia esattamente ciò che è destinato e nient’altro.

C’è stato un tempo in cui l’attività di compilazione è stata piuttosto piacevole, ma quando hai una build notturna e un test di integrazione, è meglio automatizzarlo completamente e liberarti del lavoro di routine.

ETL

Quando si automatizza il caricamento dei dati in un sistema, è spesso necessario testare varie condizioni. È necessario aggiornare le versioni esistenti delle righe e inserire quelle nuove? Avete bisogno di una trappola per evitare voci duplicate, o addirittura eliminare le voci esistenti?

Impostazione dei dati di prova.

Gli script in questo articolo utilizzano tutti una tabella dal database venerable PUBS. Useremo la tabella degli autori, ma aumenteremo il numero di righe un po ‘a 5000 per ottenere una dimensione un po’ più realistica. Ho fornito la fonte per la tabella con l’articolo.

I then created a copy of the table …

1
2
3
4
5
6

SELECT * INTO authorsCopy
FROM authors
GO
ALTER TABLE dbo.authorsCopy AGGIUNGI VINCOLO PK_authorsCopy PRIMARY KEY CLUSTERED
(au_id) SU PRIMARY
GO

E poi alterato alcune delle righe.

1
2
3
4
5

AGGIORNAMENTO authorsCopy SET indirizzo=ROBA(indirizzo,1,1,”)
DOVE au_ID IN (
SELECT TOP 10 au_id
DA authorsCopy f
ORDINE via telefono)

ora le due tabelle devono essere prevalentemente lo stesso con un paio di modifiche minori nel campo indirizzo

Test per vedere se le tabelle sono diverse.

A volte vuoi solo sapere se le tabelle sono le stesse. Un esempio di ciò potrebbe essere il controllo che un TVF funzioni correttamente confrontando il suo risultato con quello di una tabella esistente con i risultati corretti. Il solito modo per farlo è con il gruppo di funzioni CHECKSUM()in SQL Server, perché sono molto veloci.

Utilizzando Checksum

È possibile utilizzare la funzioneBINARY_CHECKSUM per verificare se le tabelle sono le stesse: beh, più o meno lo stesso. È veloce, ma non è perfetto, come dimostrerò tra un attimo. Se si dispone di una serie di test, ad esempio è generalmente sufficiente.

1
2
3
4
5
6
7
8
9

SE
SELEZIONARE la funzione checksum_agg(BINARY_CHECKSUM(*))
DAGLI autori)=(
SELEZIONARE la funzione checksum_agg(BINARY_CHECKSUM(*))
DA authorsCopy)
SELEZIONARE ‘sono probabilmente la stessa’
ALTRO
SELEZIONARE “loro sono diversi’

Affinché funzioni, la tabella non deve avere TEXT, NTEXT, IMAGE or CURSOR (o un SQL_VARIANT con uno di questi tipi) come tipo base. Al giorno d’oggi, questo è sempre più raro, ma se hai qualche tipo di complicazione, puoi costringere qualsiasi colonna con uno dei tipi non supportati in un tipo supportato. In pratica, generalmente uso una routine che controlla i metadati e lo fa automaticamente, ma non è carina.

In una versione funzionante probabilmente vorresti specificare l’elenco delle colonne, specialmente se devi fare una coercizione esplicita di tipi di dati, o se stai controllando solo determinate colonne,

BINARY_CHECKSUM() né la sua semplice sorella CHECKSUM() sono completamente accurate nel dirti se qualcosa è cambiato in una riga o in una tabella. Lo mostreremo osservando le parole comuni della lingua inglese, contenute in una tabella chiamata CommonWords.. Ti aspetteresti che tutti abbiano un checksum diverso, ma non è così.

1
2
3
4
5
6
7
8
9

SELEZIONARE la stringa, BINARY_CHECKSUM(string) AS “Checksum”
DA commonWords
DOVE BINARY_CHECKSUM(stringa) IN
(
SELEZIONARE BINARY_CHECKSUM(string)
DA commonwords
GROUP BY BINARY_CHECKSUM(string)
HAVING COUNT(*) > 2)
ORDER BY BINARY_CHECKSUM(string)

… dando il risultato …

Armati di queste informazioni, possiamo facilmente dimostrare che corde diverse possono avere lo stesso checksum

1
2
3

SELEZIONARE BINARY_CHECKSUM(‘reed il nerd’),
BINARY_CHECKSUM(‘citato in giudizio il nido”),
BINARY_CHECKSUM(‘stud the oust’)

All these will; have the same checksum, as would …

1
2
3

SELECT
BINARY_CHECKSUM(‘accosted guards’),
BINARY_CHECKSUM(‘accorded feasts’)

….considerando che…

1
2
3

SELEZIONARE BINARY_CHECKSUM(‘molto simile a successivo’),
BINARY_CHECKSUM(‘molto simile a successivo’),
BINARY_CHECKSUM(‘molto simile a Successivo’)

… ti da diversi checksum come questo…

1
2

———– ———– ———–
-447523377 -447522865 -447654449

The sister function CHECKSUM()

1
2
3
4

SELECT CHECKSUM(‘This looks very much come il successivo’),
CHECKSUM(‘molto simile a successivo’),
CHECKSUM(‘molto simile a Successivo’)

… li trova tutti uguali, perché è il confronto e le mie regole di confronto del database è case-insensitive. CHECKSUM() mira a trovare stringhe uguali nel checksum se sono uguali in un confronto di stringhe.

1
2

———– ———– ———–
-943581052 -943581052 -943581052

Così, il meglio che si può dire è che c’è una forte probabilità che le tabelle sarà lo stesso, ma se avete bisogno di per essere assolutamente certi, quindi utilizzare un altro algoritmo.

Se non ti dispiace la differenza nel caso in stringhe di testo, si può usare CHECKSUM() invece di BINARY_CHECKSUM()

Il grande valore di questa tecnica è che, una volta calcolato il checksum che avete bisogno di, è possibile memorizzare un valore in una colonna di una tabella, anziché la tabella originale e quindi è possibile effettuare l’intero processo ancora più veloce, e richiede meno tempo. Se stai memorizzando il valore di checksum restituito da CHECKSUM() assicurati di controllare la tabella live con un checksum generato con le stesse regole di confronto.

Ecco un semplice esempio della routine “cosa è cambiato”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

–creeremo un “checksum” tabella “al volo” utilizzando il menu di selezione IN.
SELEZIONA
au_ID,
BINARY_CHECKSUM(au_id, au_lname, au_fname, telefono , città , cap, ) COME
IN auchk
DA authorscopy
ORDER BY au_ID
/* ora lo mettiamo in un vincolo solo per controllare che non abbiamo vinto la lotteria (molto improbabile, ma non del tutto impossibile, che ci sono due righe con lo stesso checksum) */
ALTER TABLE AuChk AGGIUNGERE il VINCOLO di IsItUnique UNICO ()
AGGIORNAMENTO authorscopy SET au_fname= “Arthur”
DOVE au_ID=’327-89-2366′
SELEZIONARE authorscopy.*
FROM authorscopy
INNER JOIN AuChk ON authorscopy.au_ID=AuChk.au_ID
WHERE <>BINARY_CHECKSUM(authorscopy.au_id, au_lname, au_fname, phone, , city, , zip, )

…which gives…

1
2
3

au_id au_lname au_fname phone address city state zip contract
———– ——— ——— ———— ————— ————- —– —– ——–
327-89-2366 Mendoza Arthur 529275-5757 15 Hague Blvd. Piccola roccia DI 98949 1

E poi abbiamo appena riordinare.

1
2
3

/ * * * e e solo pop indietro a quello che è stato, come parte di demolizione */
AGGIORNAMENTO authorscopy SET au_fname=’Arnold’
DOVE au_ID=’327-89-2366′

naturalmente, si potrebbe utilizzare un trigger, ma a volte si potrebbe desiderare solo giornaliera o settimanale report di modifiche senza l’intrusione di un trigger in una tabella.

Usando XML

Una possibilità generale è quella di confrontare la versione XML delle due tabelle, poiché questo fa la traduzione del tipo di dati in stringhe per te. È più lento dell’approccio Checksum ma più affidabile.

1
2
3
4
5
6
7
8
9
10

IF CONVERT(VARCHAR(MAX),(
SELECT *
FROM authors ORDER BY au_id FOR XML path, root))
=
CONVERT(VARCHAR(MAX),(
SELECT *
FROM authorscopy ORDER BY au_id FOR XMLpath, root))
SELECT ‘they are the same’
ELSE
SELEZIONA ‘ sono diversi ‘

Qui puoi specificare il tipo di confronto specificando le regole di confronto.

oppure puoi farlo, confrontando i dati nelle tabelle ..

1
2
3
4
5
6
7
8
9
10

IF BINARY_CHECKSUM(CONVERT(VARCHAR(MAX),(
SELECT *
FROM authors ORDER BY au_id FOR XML path, root)))
=
BINARY_CHECKSUM (CONVERT(VARCHAR(MAX),(
SELECT *
FROM authorscopy ORDER BY au_id FOR XML path, root)))
SELEZIONA ‘ sono praticamente uguali ‘
ELSE
SELEZIONA ‘sono diversi’ SELEZIONA ‘sono diversi’

calculating calcolando un checksum della versione XML della tabella. Ciò consente di memorizzare il checksum della tabella a cui si sta confrontando.

Trovare dove si trovano le differenze in una tabella

Il compito più semplice è dove le tabelle hanno un numero identico di righe e una struttura di tabella identica. A volte vuoi sapere quali righe sono diverse e quali mancano. Devi, ovviamente, specificare cosa intendi per “lo stesso”, in particolare se le due tabelle hanno colonne diverse. Il metodo scelto per fare il confronto è generalmente determinato da questi dettagli.

The UNION ALL GROUP GROUP BY technique

L’approccio classico per confrontare le tabelle consiste nell’utilizzare unUNION ALL per leSELECT istruzioni che includono le colonne che si desidera confrontare e quindiGROUP BY quelle colonne. Ovviamente, perché funzioni, deve esserci una colonna con valori univoci nel GROUP BY, e la chiave primaria è l’ideale per questo. Nessuna delle due tabelle è consentita la duplicazione. Se hanno un numero diverso di righe, queste verranno visualizzate come differenze.

1
2
3
4
5
6
7
8
9
10
11
12
13

SELECT DISTINCT au_ID
DAL
(
SELEZIONARE au_ID
DAL
(
SELEZIONARE au_id, au_lname, au_fname, telefono, indirizzo, città, stato, zip, contratto
DA autori
UNIONE
SELEZIONARE au_id, au_lname, au_fname, telefono, indirizzo, città, stato, zip, contratto
DA authorsCopy) BothOfEm
GROUP BY au_id, au_lname, au_fname, telefono, indirizzo, città, stato, zip, contratto
HAVING COUNT(*)<2) f

Se una delle tabelle è un duplicato, quindi vi darà un risultato falso, come qui, dove vi sono due tabelle che sono molto diversi e il risultato dice che sono la stessa cosa! Per questo motivo, è una buona idea includere le colonne che costituiscono la chiave primaria e includere solo le righe una volta!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

SELECT COUNT(*), Country,Indirizzo,ThePostCode
DAL
(
SELEZIONARE Country,Indirizzo,ThePostCode
DA
(
VALORI
(9, ‘929 Agostino lane, Staple Hill Rione South Gloucestershire regno UNITO’,’BS16 4LL’),
(10, ’45 Bradfield strada, Parwich Derbyshire, regno UNITO’,’DE6 1QN’)
) tabella a(Country,Indirizzo,ThePostCode)
UNIONE
SELEZIONARE Country,Indirizzo,ThePostCode
DA
(
VALORI
(8 “‘L’Pippins”, 20 Gloucester Pl, Chirton Rione, Tyne &amp; Wear UK’,’NE29 7AD’),
(8, ”’The Pippins”, 20 Gloucester Pl, Chirton Ward, Tyne &amp; Wear UK’,’NE29 7AD’),
(9, ‘929 Augustine lane, Staple Hill Ward South Gloucestershire UK’,’BS16 4LL’),
(10, ’45 Bradfield road, Parwich Derbyshire UK’,’DE6 1QN’)
) TableB(Address_ID,TheAddress,ThePostCode)
)f
GROUP BY Address_ID,TheAddress,ThePostCode
HAVING COUNT(*)<2

… giving …

1
2
3
4

TheCount Country Indirizzo ThePostCode
———– ———– ————————- ————
(0 row(s) affected)

La tecnica può essere utilizzata per confrontare più di due tabelle. Devi soloUNION ALL le tabelle che devi confrontare e modificare la clausolaHAVING per filtrare solo le righe che non sono in tutte le tabelle.

Usando EXCEPT

Ora puoi usare il molto più pulito e leggermente più veloce EXCEPT.

1
2
3

SELECT * from autori
SALVO
SELECT * from authorsCopy

mostra tutte le righe di autori che non si trovano in authorsCopy. Se sono la stessa cosa, avrebbe restituito nessun righe

1
2
3
4
5
6
7
8
9
10
11
12
13
14

au_id au_lname au_fname telefono indirizzo città c.a.p. contratto
———– ———– ——— ———— ————————– ———– —– —– ——–
041-76-1076 Sosa Sonja 000-198-8753 29 Second Avenue Omaha CT 23243 0
187-42-2491 Mc Connell Trenton 0003090766 279 Aia San Diego NY 94940 1
220-43-7067 Judith Fox 000-137-9418 269 Est Via Aia Richmond VA 55027 0
505-28-2848 Hardy Mitchell 001-2479822 73 Verde Milton Auto Norfolk WA 69949 1
697-84-0401 Montes Leanne 000-018-0454 441 East Oak Parkway San Antonio MD 38169 1
727-35-9948 Lungo Jonathon 000-8761152 280 Nobel Avenue di Ancoraggio LA NULL, 1
875-54-8676 Pietra Keisha 000-107-1947 763 Bianco Fabien Modo Fremont ND 08520 0
884-64-5876 Keller Steven 000-2787554 45 Bianco Nobel Boulevard Milwaukee NY 29108 1
886-75-9197 Ellis Marie 001032-5109 35 East Second Boulevard Chicago IL 32390 1
975-80-3567 Salazar Johanna 001-028-0716 17 Nuovo Boulevard Jackson ND 71625 0
(10 righe interessate:)

io sto usando solo SELEZIONARE * per mantenere le cose semplici per l’articolo. Normalmente descriveresti tutte le colonne che vuoi confrontare.

Questo funzionerà solo per le tabelle con lo stesso numero di righe perché, se gli autori avessero righe extra, direbbe comunque che erano diverse poiché le righe negli Autori che non erano in authorsCopy verrebbero restituite. Questo perché EXCEPT restituisce tutti i valori distinti della query a sinistra del EXCEPT operando non presenti dalla query sulla destra

Questo, speriamo che mostra quello che voglio dire

1
2
3
4
5
6
7
8
9
10
11
12
13
14

SELEZIONARE Country,Indirizzo,ThePostCode
DA
(VALORI
(9, ‘929 Agostino lane, Staple Hill Rione South Gloucestershire regno UNITO’,’BS16 4LL’),
(10, ’45 Bradfield strada, Parwich Derbyshire, regno UNITO’,’DE6 1QN’)
) tabella a(Country,Indirizzo,ThePostCode)
SALVO
SELEZIONARE Country,Indirizzo,ThePostCode da
(VALORI
(8 “‘L’Pippins”, 20 Gloucester Pl, Chirton Rione, Tyne & Indossare UK’,’NE29 7AD’),
(8 “‘L’Pippins”, 20 Gloucester Pl, Chirton Rione, Tyne & Wear UK’,’NE29 7AD’),
(9, ‘929 Augustine lane, Staple Hill Ward South Gloucestershire UK’,’BS16 4LL’),
(10, ’45 Bradfield road, Parwich Derbyshire UK’,’DE6 1QN’)
) TableB(Address_ID,TheAddress,ThePostCode)

…yields …

1
2
3
4

Address_ID TheAddress ThePostCode
———– ———————————————- ———–
(0 row(s) affected)

…mentre …

1
2
3
4
5
6
7
8
9
10
11
12
13
14

SELEZIONARE Country,Indirizzo,ThePostCode DA
(VALORI
(8 “‘L’Pippins”, 20 Gloucester Pl, Chirton Rione, Tyne & Indossare UK’,’NE29 7AD’),
(8 “‘L’Pippins”, 20 Gloucester Pl, Chirton Rione, Tyne & Indossare UK’,’NE29 7AD’),
(9, ‘929 Agostino lane, Staple Hill Rione South Gloucestershire regno UNITO’,’BS16 4LL’),
(10, ’45 Bradfield strada, Parwich Derbyshire, regno UNITO’,’DE6 1QN’)
) tabella b(Country,Indirizzo,ThePostCode)
SALVO
SELEZIONARE Country,Indirizzo,ThePostCode
DA
(VALORI
(9, ‘929 Agostino lane, Staple Hill Rione South Gloucestershire regno UNITO’,’BS16 4LL’),
(10, ’45 Bradfield strada, Parwich Derbyshire, regno UNITO’,’DE6 1QN’)
) tabella a(Country,Indirizzo,ThePostCode)

..results in …

1
2
3
4
5

Address_ID TheAddress ThePostCode
———– ————————————————————- ———–
8 ‘The Pippins’, 20 Gloucester Pl, Chirton Ward, Tyne & Wear UK NE29 7AD
(1 row(s) affected)

Questa funzionalità di EXCEPTpotrebbe essere utilizzata a vantaggio se si desidera verificare che TableAsia contenuta in TableB. Quindi, dove le tabelle hanno un numero diverso di righe, puoi comunque confrontarle.

Potresti non voler confrontare tutte le colonne. Si dovrebbe sempre specificare quelle colonne che si desidera confrontare per determinare ‘identità’. Se solo si desidera confrontare l’Indirizzo, ad esempio, devi utilizzare …

1
2
3

SELEZIONARE l’indirizzo DA autori
SALVO
SELEZIONARE indirizzo authorsCopy

Outer Join tecnica

C’è anche la tecnica di outer join. Questa è una tecnica più generale che ti offre servizi aggiuntivi. Se, ad esempio, si utilizza il join esterno completo, è possibile ottenere le righe non corrispondenti in entrambe le tabelle. Questo ti dà una vista “prima” e “dopo” delle alterazioni nei dati. Viene utilizzato più in generale nella sincronizzazione per dirti quali righe eliminare, inserire e aggiornare.

We’ll just use the technique to get the altered rows in authorsCopy

1
2
3
4
5
6
7
8
9
10
11
12
13

SELECT authors.au_id, authors.au_lname, authors.au_fname, authors.phone, authors.address, authors.city, authors.state, authors.zip, authors.contract
FROM authors
LEFT OUTER JOIN authorsCopy
ON authors.au_ID = AuthorsCopy.au_ID
AND authors.au_lname =authorsCopy.au_lname
AND authors.au_fname =authorsCopy.au_name
AND authors.telefono = authorsCopy.telefono
E COALESCE (autori.indirizzo,”)=COALESCE (authorsCopy.indirizzo,”)
E COALESCE (autori.città,”) = COALESCE (authorsCopy.città,”)
E COALESCE (autori.stato,”) = COALESCE (authorsCopy.stato,”)
E COALESCE (autori.zip,”) =COALESCE (authorsCopy.zip,”)
E autori.contratto =authorsCopy.contratto
DOVE authorsCopy.au_ID È NULL

Come potete vedere, ci sono difficoltà con le colonne null con questo approccio, ma è così veloce come gli altri e ti dà più flessibilità per i vostri confronti.

Localizzando le differenze tra le tabelle

Potresti aver bisogno di un modo rapido per vedere quale colonna e riga sono cambiate. Un modo molto ingegnoso di farlo è stato pubblicato di recente. Ha usato XML. ‘Confronta le tabelle e segnala le differenze usando Xml per ruotare i dati ‘(nota dell’editore: link deprecato). È intelligente, ma troppo lento. La stessa cosa può essere fatta puramente in SQL. Fondamentalmente, si esegue un confronto colonna per colonna di dati in base alla chiave primaria, utilizzando una coppia chiave/valore. Se fai l’intero tavolo in una volta è piuttosto lento: il trucco migliore è farlo solo su quelle righe in cui sai che c’è una differenza.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

AFFERMANDO @temp TABELLA(au_id VARCHAR(11) CHIAVE PRIMARIA) /*questo detiene le chiavi primarie delle righe modificate */
INSERISCI IN @Temp(au_ID) –determinare quali righe sono state modificate
SELEZIONARE au_ID
DA –utilizzare l’ECCEZIONE di tecnica qhich è il più veloce nei test
(
SELEZIONARE au_id, au_lname, au_fname, telefono , città, stato, zip,
DA autori
SALVO
SELEZIONARE au_id, au_lname, au_fname, telefono, indirizzo, città, stato, zip, contratto
DA authorsCopy
)f–ora basta SELEZIONARE le colonne che hanno cambiato
SELEZIONARE a sinistra.au_id,sinistra.nome,a sinistra.valore COME l’originale,a Destra.il valore, COME modificato
DA (–ora basta stendere le due tabelle, come coppie chiave-valore, utilizzando la stringa versioni dei dati
SELEZIONARE gli autori.au_id, ‘au_lname’ COME ‘nome’,au_lname COME ‘valore’
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, ‘au_fname’ COME ‘nome’,au_fname COME ‘valore’
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, ‘telefono’,telefono
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, indirizzo,indirizzo
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, ‘Città’ COME ‘nome’,Città COME ‘valore’
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, ‘Stato’,stato
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, ‘zip’,zip
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id
UNIONE
SELEZIONARE gli autori.au_id, ‘contratto’,CONVERT(CHAR(1),contratto)
DA autori INNER JOIN @Temp alterato alterato.au_id=autori.au_id LeftHand
INNER JOIN (
SELEZIONARE authorsCopy.au_id, ‘au_lname’ COME ‘nome’,au_lname COME ‘valore’
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id, ‘au_fname’,au_fname
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id, ‘telefono’,telefono
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id, indirizzo,indirizzo
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id, ‘Città’ COME ‘nome’,Città COME ‘valore’
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id, ‘Stato’,stato
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id, ‘zip’,zip
DA authorsCopy INNER JOIN @Temp alterato alterato.au_id=authorsCopy.au_id
UNIONE
SELEZIONARE authorsCopy.au_id,’contract’, CONVERT(CHAR(1), contract)
FROM authorsCopy INNER JOIN @ Temp altered ON altered.au_id=authorsCopy.au_id) rightHand
ON lefthand.au_ID=righthand. au_ID
AND lefthand.name=righthand.name
DOVE a sinistra.valore <>a destra.valore

nel nostro esempio, questo darebbe:

1
2
3
4
5
6
7
8
9
10
11
12

au_id nome originale modificato
———– ——– —————————- ————————————
041-76-1076 indirizzo 29, Secondo Avenue 9 Second Avenue
187-42-2491 indirizzo 279 Aia Modo 79 Aia Modo
220-43-7067 indirizzo 269 Est Via Aia 69 Est Via Aia
505-28-2848 indirizzo 73 Verde Milton Auto 3 Verde Milton Auto
697-84-0401 indirizzo 441 East Oak Parkway 41 East Oak Parkway
727-35-9948 indirizzo 280 Nobel Avenue 80 Nobel Avenue
875-54-8676 indirizzo 763 Bianco Fabien Modo 63 Bianco Fabien Modo
884-64-5876 indirizzo 45 Bianco Nobel Boulevard 5 Bianco Nobel Boulevard
886-75-9197 indirizzo 35 East Second Boulevard 5 Boulevard East Second
975-80-3567 indirizzo 17 Nuovo Boulevard 7 Nuovo Boulevard

Questa tecnica ruota le righe delle tabelle che presentano differenze in una tabella EAV (Entity-Attribute-value) in modo che le differenze all’interno di una riga possano essere confrontate e visualizzate. Fa questa rotazione conUNIONing il nome e il valore stringa di ogni colonna. Questa tecnica funziona meglio dove non ci sono un gran numero di differenze.

Conclusioni

Non esiste un unico metodo ideale per confrontare i dati in tabelle o risultati. Una delle numerose tecniche sarà la più rilevante per qualsiasi compito particolare. Tutto dipende precisamente dalle risposte di cui hai bisogno e dal tipo di attività. Hai bisogno di un rapido controllo che una tabella non sia cambiata o hai bisogno di sapere esattamente quali sono le modifiche? SQL è naturalmente veloce a fare questo compito e confronti di tabelle e risultati è un compito familiare a molti sviluppatori di database.

Se esiste una regola generale, direi che il lavoro esplorativo o ad hoc richiede uno strumento come SQL Data Compare, mentre un processo di routine all’interno del database richiede una tecnica SQL tagliata a mano.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *