Articles

Redgate Hub

Introducere

există mai multe motive de ce ar putea fi necesar pentru a compara tabele sau rezultate.

  • uneori, trebuie doar să știm dacă tabelele conțin date identice sau diferite; fără detalii: doar da sau nu. Acest lucru este tipic pentru afirmațiile de testare, unde trebuie doar să știți dacă rutina sau lotul dvs. produce un rezultat cu datele corecte din acesta. atunci când este prevăzut cu vales special pentru parametrii. Este fie greșit, fie corect
  • ocazional, trebuie să știți ce rânduri s-au schimbat fără, Poate, a fi special despre ce coloane s-au schimbat și cum.
  • există momente în care aveți un tabel mare atât în ceea ce privește coloanele, cât și rândurile și aveți nevoie de ceva care să vă arate în mod specific coloanele care le-au schimbat valoarea. S-ar putea să doriți acest lucru și atunci când urmăriți un bug într-o rutină care altfel ar putea necesita să pierdeți timpul scanând ‘cu ochii’.

vom aborda aceste trei sarcini destul de diferite în SQL

Dacă două tabele au un număr diferit de rânduri, ele nu pot fi, desigur, la fel. Cu toate acestea, există momente când trebuie să știți dacă Table_B conține toate rândurile Table_A, fără diferențe. Dacă doriți mai multe detalii, s-ar putea dori chiar să știe rândurile din oricare tabel care nu sunt în comun, sau rândurile comune, așa cum este indicat de cheia primară, care au fost diferite. De ce să comparăm doar două tabele? Există modalități de a compara cât de multe aveți nevoie. (ca, de exemplu, atunci când comparați metadatele în mai multe instantanee ale bazei de date). Da, există mai multe variante

ai Instrumente și caracteristici pentru a face aceste lucruri, cu siguranță?

există întotdeauna un loc pentru instrumente precum SQL Data Compare, TableDiff, tSQLt sau Change Data Capture. Multe depind de circumstanțe și de tipul de sarcină. Problema efectuării auditurilor privind modificările datelor într-un sistem live este un subiect separat, la fel ca și sincronizarea tabelelor și bazelor de date. Compararea documentelor XML sunt, de asemenea, în afara domeniului de aplicare. Ne vom ocupa doar de comparația de rutină a datelor din tabele

sunt cel mai probabil să folosesc tehnici TSQL pentru a compara tabelele atunci când:

dezvoltarea…

în cursul dezvoltării unei baze de date, o mulțime de tabele se compară. Nu este vorba doar de lucrurile mari: Fiecare funcție cu valoare de masă, de exemplu, are nevoie de un ham de testare în scriptul de construire care să se asigure că face ceea ce credeți că ar trebui să facă în toate circumstanțele de testare imaginabile și încorporează toate cazurile de margine urâte în care a fost prins de testeri în trecut. Fiecare procedură stocată are nevoie de un test pentru a vă asigura că procesul pe care îl execută face exact ceea ce este intenționat și nimic altceva.

a fost o perioadă în care activitatea de construire a fost destul de pe îndelete, dar când ai un test de construire și integrare nocturnă, cel mai bine este să o automatizezi în întregime și să scapi de corvoadă.

ETL

când automatizați încărcarea datelor într-un sistem, de multe ori trebuie să testați diferite condiții. Trebuie să actualizați versiunile existente ale rândurilor, precum și să le introduceți pe cele noi? Ai nevoie de o capcană pentru a preveni intrările duplicat, sau chiar șterge intrările existente?

configurarea datelor de testare.

scripturile din acest articol folosesc toate un tabel din Baza de date venerable PUBS. Vom folosi tabelul autorilor, dar vom crește numărul de rânduri puțin până la 5000 pentru a obține o dimensiune puțin mai realistă. Am furnizat sursa pentru tabel cu articolul.

I then created a copy of the table …

1
2
3
4
5
6

SELECT * INTO authorsCopy
FROM authors
GO
ALTER TABLE dbo.authorsCopy adăugați constrângere PK_AUTHORSCOPY cheie primară grupate
(au_id) pe primar
merge

și apoi modificat unele rânduri.

1
2
3
4
5

actualizare authorscopy set address=Stuff(adresa,1,1,”)
unde au_id în (
selectați top 10 au_id
din authorscopy f
comanda prin telefon)

deci, acum cele două tabele ar trebui să fie predominant la fel cu câteva modificări minore în câmpul de adresă

testarea pentru a vedea dacă tabelele sunt diferite.

uneori vrei doar să știi dacă tabelele sunt aceleași. Un exemplu în acest sens ar fi verificarea faptului că un TVF funcționează corect prin compararea rezultatului său cu cel al unui tabel existent cu rezultatele corecte. Modul obișnuit de a face acest lucru este cu CHECKSUM()grup de funcții în SQL Server, deoarece acestea sunt foarte rapide.

folosind sumele de control

puteți utiliza funcțiaBINARY_CHECKSUM pentru a verifica dacă tabelele sunt aceleași: ei bine, aproximativ la fel. Este rapid, dar nu este perfect, așa cum voi demonstra într-o clipă. Dacă aveți o serie de teste, de exemplu, este în general suficient.

1
2
3
4
5
6
7
8
9

dacă (
selectați checksum_agg(binary_checksum(*))
de la autori)=(
selectați checksum_agg(binary_checksum(*))
de la authorscopy)
selectați ‘sunt probabil aceleași’
altfel
selectați ‘sunt diferite’

pentru ca acest lucru să funcționeze, tabelul dvs. nu trebuie să aibăTEXT, NTEXT, IMAGE or CURSOR (sau unSQL_VARIANTcu oricare dintre aceste tipuri) ca tip de bază. În zilele noastre, acest lucru este din ce în ce mai rar, dar dacă aveți orice fel de complicație, puteți constrânge orice coloană cu unul dintre tipurile neacceptate într-un tip acceptat. În practică, folosesc în general o rutină care verifică metadatele și face acest lucru automat, dar nu este frumos.

într-o versiune de lucru probabil doriți să specificați lista coloanelor, mai ales dacă trebuie să faceți o constrângere explicită a tipurilor de date sau dacă verificați doar anumite coloane,

nici BINARY_CHECKSUM() nici sora sa simplăCHECKSUM() nu sunt complet corecte în a vă spune dacă ceva s-a schimbat într-un rând sau într-un tabel. Vom arăta acest lucru uitându-ne la cuvintele comune ale limbii engleze, conținute într-un tabel numit CommonWords.. Te-ai aștepta ca toți să aibă o sumă de control diferită, dar nu este cazul.

1
2
3
4
5
6
7
8
9

selectați șir, binary_checksum(șir) ca „checksum”
din commonwords
unde binary_checksum(șir) în
(
selectați binary_checksum(șir)
din commonwords
grup de binary_checksum(șir)
având număr (*) > 2)
ordine de BINARY_CHECKSUM(string)

… dând rezultatul …

înarmați cu aceste informații, putem demonstra rapid că diferite șiruri pot avea aceleași suma de control

1
2
3

selectați binary_checksum(‘reed tocilar’),
binary_checksum(‘dat în judecată cuib’),
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’)

….întrucât…

1
2
3

selectați binary_checksum(‘acesta seamănă foarte mult cu următorul’),
binary_checksum(‘acesta seamănă foarte mult cu următorul’),
binary_checksum(‘acesta seamănă foarte mult cu următorul’)

… vă oferă diferite sume de control ca aceasta…

1
2

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

The sister function CHECKSUM()

1
2
3
4

SELECT CHECKSUM(‘This looks very much ca următorul’),
CHECKSUM(‘acest lucru arata foarte mult ca următorul’),
CHECKSUM(‘acest lucru arata foarte mult ca următorul’)

… le găsește să fie toate la fel, pentru că este folosind colaționarea curent și colaționarea pentru baza de date este insensibilă la majuscule. CHECKSUM() își propune să găsească șiruri egale în suma de control dacă sunt egale într-o comparație de șiruri.

1
2

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

deci, cel mai bun lucru pe care îl puteți spune este că există o mare probabilitate ca tabelele să fie aceleași, dar dacă trebuie să fiți absolut siguri, utilizați un alt algoritm.

dacă nu vă deranjează diferența în cazul șirurilor de text, atunci puteți utiliza CHECKSUM() în loc de BINARY_CHECKSUM()

marea valoare a acestei tehnici este că, odată ce ați calculat suma de control de care aveți nevoie, o puteți stoca ca valoare în coloana unui tabel în loc să aveți nevoie de tabelul original și, prin urmare, puteți face întregul proces chiar mai repede, și să ia mai puțin timp. Dacă stocați valoarea sumei de control returnată deCHECKSUM() asigurați-vă că verificați tabelul live cu o sumă de control generată cu aceeași colaționare.

Iată un exemplu simplu al rutinei ‘ce s-a schimbat’.

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

– vom crea un tabel „checksum „”on the fly” folosind selectați în.
selectați
AU_ID,
BINARY_CHECKSUM(au_id, au_lname, au_fname, telefon, , oraș, , zip, ) ca
în auchk
din authorscopy
comanda de au_ID
/ * acum vom pune într-o constrângere doar pentru a verifica că nu am câștigat la loterie (foarte puțin probabil, dar nu complet imposibil că avem două rânduri cu aceeași sumă de control) * /
ALTER TABLE auchk adăugați constrângere isitunique unique ()
actualizați authorscopy set au_fname=’Arthur’
unde au_id=’327-89-2366′
selectați 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. Little Rock din 98949 1

și apoi ne-am ordonat.

1
2
3

/* și noi doar pop-l înapoi la ceea ce a fost, ca parte a teardown */
actualizare authorscopy set au_fname=’Arnold’
unde au_id=’327-89-2366′

desigur, ai putea folosi un declanșator, dar uneori s-ar putea dori doar un raport zilnic sau săptămânal de modificări, fără intruziunea unui declanșator într-un tabel.

folosind XML

o posibilitate generală este de a compara versiunea XML a celor două tabele, deoarece aceasta face traducerea tipului de date în șiruri pentru dvs. Este mai lent decât abordarea sumelor de control, dar mai fiabil.

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
selectați ‘sunt diferite’

aici puteți specifica tipul de comparație specificând colaționarea.

sau puteți face acest lucru, comparând datele din tabele ..

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)))
selectați ‘sunt cam la fel’
altfel
selectați ‘sunt diferite’ selectați ‘sunt diferite’

… calculând o sumă de control a versiunii XML a tabelului. Acest lucru vă permite să stocați suma de control a tabelului cu care comparați.

găsirea unde diferențele sunt într-un tabel

cea mai simplă sarcină este în cazul în care tabelele au un număr identic de rânduri, și o structură de tabel identică. Uneori doriți să știți care rânduri sunt diferite și care lipsesc. Trebuie, desigur, să specificați ce înțelegeți prin ‘același’, mai ales dacă cele două tabele au coloane diferite. Metoda pe care o alegeți pentru a face comparația este în general determinată de aceste detalii.

grupul UNION ALL … după tehnică

abordarea clasică a comparării tabelelor este de a utiliza unUNION ALL pentruSELECT declarații care includ coloanele pe care doriți să le comparați și apoiGROUP BY acele coloane. Evident, pentru ca acest lucru să funcționeze, trebuie să existe o coloană cu valori unice în GROUP BY, iar cheia primară este ideală pentru aceasta. Nici tabelul sunt permise duplicate. Dacă au un număr diferit de rânduri, acestea vor apărea ca diferențe.

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

selectați au_id distinct
din
(
selectați au_id
din
(
selectați au_id, au_lname, au_fname, telefon, adresă, oraș, stat, zip, contract
de la autori
Uniunea toate
selectați au_id, au_lname, au_fname, telefon, Adresă, Oraș, Stat, zip, contract
din authorsCopy) BothOfEm
grup de au_id, au_lname, au_fname, telefon, Adresă, Oraș, Stat, zip, contract
având număr(*)<2) f

dacă unul dintre tabele are un duplicat, atunci vă va da un rezultat fals, ca aici, unde aveți două tabele care sunt foarte diferite și rezultatul vă spune că sunt la fel! Din acest motiv, este o idee bună să includeți coloana(coloanele) care constituie cheia primară și să includeți rândurile o singură dată!

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

selectați count(*), address_id,theaddress,thepostcode
din
(
selectați Adresa_id,adresa,codul poștal
din
(
valori
(9, ‘929 Augustine lane, Staple Hill Ward South Gloucestershire UK’,’BS16 4LL’),
(10, ’45 Bradfield road, Parwich Derbyshire UK’,’DE6 1QN’)
) Tablea(Address_id,theadress,thepostcode)
Uniunea toate
selectați ADDRESS_ID,theadress,thepostcode
din
(
valori
(8, „‘Pippins”, 20 Gloucester PL, CHIRTON Ward, 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

adresa Contului_id adresa codului poștal
———– ———– ————————- ————
(0 rânduri afectate)

tehnica poate fi utilizată pentru compararea a mai mult de două tabele. Trebuie doar săUNION ALLtabelele pe care trebuie să le comparați și să modificați clauzaHAVINGpentru a filtra doar rândurile care nu sunt în toate tabelele.

folosind cu excepția

puteți utiliza acum mult mai curat și ușor mai rapidEXCEPT.

1
2
3

selectați * de la autori
cu excepția
selectați * de la autori

aceasta arată toate rândurile din autori care nu se găsesc în authorscopy. În cazul în care acestea sunt aceleași, s-ar întoarce nici un rând

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

au_id au_lname au_fname adresa de telefon oraș stat contract zip
———– ———– ——— ———— ————————– ———– —– —– ——–
041-76-1076 Sosa Sonja 000-198-8753 29 Second Avenue Omaha CT 23243 0
187-42-2491 Mc Connell Trenton 0003090766 279 Haga Way San Diego NY 94940 1
220-43-7067 Fox Judith 000-137-9418 269 East Hague Street Richmond VA 55027 0
505-28-2848 Hardy Mitchell 001-2479822 73 Green Milton drive Norfolk wa 69949 1
697-84-0401 montes Leanne 000-018-0454 441 East Oak Parkway San Antonio MD 38169 1
727-35-9948 long Jonathon 000-8761152 280 Nobel Avenue Anchorage la null 1
875-54-8676 Stone Keisha 000-107-1947 763 Alb Fabien way Fremont ND 08520 0
884-64-5876 Keller Steven 000-2787554 45 White 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 New Boulevard Jackson nd 71625 0
(10 rânduri afectate)

folosesc doar selectați * pentru a menține lucrurile simple pentru articol. În mod normal, ați enumera toate coloanele pe care doriți să le comparați.

Acest lucru va funcționa numai pentru tabele cu același număr de rânduri, deoarece, dacă autorii ar avea rânduri suplimentare, ar spune totuși că sunt diferite, deoarece rândurile din autori care nu erau în authorsCopy ar fi returnate. Acest lucru se datorează faptului că EXCEPT returnează orice valori distincte din interogarea din stânga EXCEPT operand care nu se găsesc și din interogarea din dreapta

aceasta, sperăm că arată ce vreau să spun

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

Selectați Adresa_id,adresa,codul poștal
din
(valori
(9, ‘929 Augustine lane, Staple Hill Ward South Gloucestershire UK’,’BS16 4LL’),
(10, ’45 Bradfield road, Parwich Derbyshire UK’,’DE6 1QN’)
) ADRESA_ID,adresa,codul poștal)
cu excepția
selectați ADRESA_ID,adresa,codul poștal din
(valori
(8, „‘Pippins”, 20 Gloucester pl, chirton ward, Tyne & wear UK’,’ne29 7ad’),
(8, „‘Pippins”, 20 Gloucester pl, chirton ward, 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 Cod poștal
———– ———————————————- ———–
(0 rând(e) afectate)

…întrucât …

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

selectați Adresa_id,adresa,codul poștal de la
(valori
(8, „‘Pippins”, 20 Gloucester Pl, Chirton Ward, Tyne & Wear UK’,’NE29 7AD’),
(8, „‘Pippins”, 20 Gloucester Pl, Chirton Ward, Tyne & wear UK’,’ne29 7ad’),
(9, ‘929 Augustine Lane, capse Hill ward South Gloucestershire UK’,’BS16 4LL’),
(10, ’45 Bradfield Road, parwich Derbyshire UK’,’DE6 1QN’)
) tableb(address_id,Theadress,ThePostCode)
cu excepția
selectați address_id,Theadress,Thepostcode
din
(valori
(9, ‘929 Augustine lane, discontinue Hill Ward South Gloucestershire UK’,’BS16 4LL’),
(10, ’45 Bradfield road, Parwich Derbyshire UK’,’DE6 1QN’)
) TableA(Adresa_id,adresa,codul poștal)

..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)

această caracteristică a EXCEPTar putea fi utilizată în avantaj dacă doriți în mod special să verificați dacă TableAeste conținută în TableB. Deci, în cazul în care tabelele au un număr diferit de rânduri, le puteți compara în continuare.

s-ar putea să nu doriți să comparați toate coloanele. Ar trebui să specificați întotdeauna acele coloane pe care doriți să le comparați pentru a determina ‘similitudine’. Dacă ați vrut doar să comparați adresa, de exemplu, ați folosi …

1
2
3

selectați adresa de autori
cu excepția
selectați adresa de autorcopie

tehnica de îmbinare exterioară

există și tehnica îmbinării exterioare. Aceasta este o tehnică mai generală care vă oferă facilități suplimentare. Dacă, de exemplu, utilizați unirea exterioară completă, puteți obține rândurile de neegalat în oricare dintre tabele. Aceasta vă oferă o vizualizare’ înainte’ și ‘după’ a modificărilor datelor. Este folosit mai general în sincronizare pentru a vă spune ce rânduri să ștergeți, inserați și actualizați.

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
de la autori
stânga exterior se alăture authorsCopy
pe autori.au_id = AuthorsCopy.au_id
și autori.au_lname =authorsCopy.au_name
și autori.au_fname =authorsCopy.au_name
și autori.au_fname = authorsCopy. au_name
.telefon = authorsCopy.telefon
și COALESCE (autori.adresa,”)=COALESCE (authorsCopy.adresa,”)
și COALESCE(autori.oraș,”) =COALESCE (authorsCopy.oraș,”)
și COALESCE(autori.stat,”) =COALESCE(authorsCopy.stat,”)
și COALESCE(autori.zip,”) =COALESCE (authorsCopy.zip,”)
și autori.contract =authorsCopy.contract
unde authorsCopy.au_id este NULL

după cum puteți vedea, există dificultăți cu coloane nule cu această abordare, dar este la fel de rapid ca și celelalte și vă oferă mai degrabă mai multă versatilitate pentru comparații.

localizarea diferențelor dintre tabele

este posibil să aveți nevoie de o modalitate rapidă de a vedea ce coloană și rând s-au schimbat. Un mod foarte ingenios de a face acest lucru a fost publicat recent. A folosit XML. ‘Comparați tabelele și raportați diferențele utilizând Xml pentru a pivota datele ‘(Nota editorului: link depreciat). Este inteligent, dar prea lent. Același lucru se poate face pur și simplu în SQL. Practic, efectuați o comparație coloană cu coloană a datelor pe baza cheii primare, utilizând o pereche cheie/valoare. Dacă faceți întregul tabel simultan, este destul de lent: cel mai bun truc este să faceți acest lucru numai pe acele rânduri în care știți că există o diferență.

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

precizând tabelul temp(au_id varchar(11) cheie primară) /*aceasta deține cheile primare ale rândurilor care s-au schimbat */
inserare În @Temp(Au_id) – determinați ce rânduri s-au schimbat
selectați AU_ID
din-utilizați tehnica cu excepția qhich este cel mai rapid în testele noastre
(
selectați AU_ID, au_lname, au_fname, telefon, , Oraș, Stat, zip,
de la autori
cu excepția
selectați au_id, au_lname, au_fname, telefon, adresa, oraș, stat, zip, contract
din authorscopy
)F-acum vom selecta doar acele coloane care s-au schimbat
selectați lefthand.au_id,lefthand.name, mâna stângă.valoare ca originală, mâna dreaptă.valoare modificată
din (–now we just lay out the two tables as key value pairs, using the string versions of the data
SELECT authors.AU_ID, ‘au_lname’ AS ‘name’,au_lname AS ‘value’
FROM authors inner JOIN @Temp altered ON altered.au_id=authors.au_id
UNION
SELECT authors.au_id, ‘au_fname’ as ‘name’,au_fname as ‘value’
from authors inner join @Temp altered on altered.au_id=authors.au_id
Union
select authors.AU_ID, ‘phone’,phone
from authors inner join @Temp altered on altered.AU_ID=authors.Au_id
UNION
SELECT authors.AU_ID, ‘address’,address
FROM authors inner JOIN @Temp altered ON altered.au_id=authors.au_id
UNION
SELECT authors.AU_ID, ‘City’ AS ‘name’,City AS ‘value’
FROM authors inner JOIN @Temp altered ON altered.au_id=authors.Au_id
UNION
SELECT authors.Au_id, ‘City’AS ‘ name’, City AS ‘value’
FROM authors INNER JOIN @Temp altered ON altered.au_id=authors.au_id
Union
select authors.au_id, ‘state’, state
from authors inner join @ Temp altered on altered. au_id = authors. au_id
Union
select authors.au_id, ‘zip’,zip
de la autori inner JOIN @Temp altered ON altered.au_id=autori.AU_ID
Uniune
selectați autori.AU_ID, ‘contract’,CONVERT(CHAR(1),contract)
de la autori inner JOIN @Temp altered ON altered.au_id=autori.au_id) LeftHand
inner JOIN (
selectați authorscopy.au_id, ‘AU_LNAME’ ca ‘nume’,au_lname ca ‘valoare’
din authorscopy inner join @Temp altered on altered.au_id=authorscopy.au_id
Union
selectați authorscopy.au_id, ‘au_fname’,au_fname
de la authorsCopy inner JOIN @Temp altered ON altered.au_id=authorsCopy.au_id
UNION
SELECT authorsCopy.AU_ID, ‘phone’,phone
de la authorsCopy inner JOIN @Temp altered ON altered.au_id=authorsCopy.au_id
UNION
selectați authorscopy.au_id, ‘address’,address
de la Authorscopy inner join @Temp altered on altered.au_id=authorscopy.au_id
Union
selectați authorscopy.au_id=authorsCopy.au_id
selectați authorsCopy.AU_ID, ‘State’, ‘value’
de la authorsCopy inner JOIN @Temp altered ON altered.au_id=authorsCopy.AU_ID
Union
state
FROM authorsCopy inner JOIN @Temp altered ON altered.au_id=authorsCopy.au_id
UNION

selectați authorscopy.Au_id, ‘zip’, zip
din Authorscopy inner join @Temp altered on altered.Au_id = authorscopy.Au_id
Union
selectați authorscopy.au_id, ‘contract’, CONVERT(CHAR (1),contract)
de la authorsCopy inner JOIN @Temp altered pe altered.au_id=authorsCopy.au_id) rightHand
pe lefthand.au_id=righthand.AU_ID
și lefthand.name=righthand.name
unde lefthand.valoare <>mâna dreaptă.valoare

în exemplul nostru, acest lucru ar da:

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

numele au_id original schimbat
———– ——– —————————- ————————————
041-76-1076 adresa 29 Second Avenue 9 Second Avenue
187-42-2491 adresa 279 Haga Way 79 Haga Way
220-43-7067 adresa 269 East Hague Street 69 East Hague Street
505-28-2848 adresa 73 Green Milton Drive 3 Green Milton Drive
697-84-0401 adresa 441 East Oak Parkway 41 East Oak Parkway
727-35-9948 adresa 280 Nobel Avenue 80 Nobel Avenue
875-54-8676 adresa 763 White Fabien way 63 White Fabien way
884-64-5876 adresa 45 White Nobel Boulevard 5 white Nobel Boulevard
886-75-9197 adresa 35 East Second Boulevard 5 East Second Boulevard
975-80-3567 adresa 17 New Boulevard 7 New Boulevard

această tehnică rotește rândurile tabelelor care au diferențe într-un tabel entitate-atribut-valoare (EAV), astfel încât diferențele dintr-un rând să poată fi comparate și afișate. Ea face această rotație deUNIONing numele și string-valoarea fiecărei coloane. Această tehnică funcționează cel mai bine acolo unde nu există un număr mare de diferențe.

concluzii

nu există o singură metodă ideală de comparare a datelor din tabele sau rezultate. Una dintre mai multe tehnici va fi cea mai relevantă pentru o anumită sarcină. Totul depinde de exact răspunsurile de care aveți nevoie și de tipul de sarcină. Aveți nevoie de o verificare rapidă a faptului că un tabel nu s-a schimbat sau trebuie să știți exact care sunt modificările? SQL este în mod natural rapid la a face această sarcină și comparații de tabele și rezultate este o sarcină familiară pentru mulți dezvoltatori de baze de date.

dacă există o regulă generală, aș spune că munca exploratorie sau ad-hoc are nevoie de un instrument precum SQL Data Compare, în timp ce un proces de rutină din Baza de date necesită o tehnică SQL tăiată manual.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *