Articles

Redgate Hub

Einführung

Es gibt mehrere Gründe, warum Sie Tabellen oder Ergebnisse vergleichen müssen.

  • Manchmal muss man nur wissen, ob die Tabellen Daten enthalten, die gleich oder verschieden sind; Keine Details: nur ja oder nein. Dies ist typisch für Testassertionen, bei denen Sie nur wissen müssen, ob Ihre Routine oder Ihr Batch ein Ergebnis mit den richtigen Daten liefert. wenn mit bestimmten Werten für die Parameter versehen. Es ist entweder falsch oder richtig
  • Gelegentlich müssen Sie wissen, welche Zeilen sich geändert haben, ohne möglicherweise genau zu wissen, welche Spalten sich wie geändert haben.
  • Es gibt Zeiten, in denen Sie eine große Tabelle in Bezug auf Spalten und Zeilen haben und etwas benötigen, das Ihnen speziell die Spalten anzeigt, die ihren Wert geändert haben. Möglicherweise möchten Sie dies auch, wenn Sie einen Fehler in einer Routine aufspüren, bei der Sie andernfalls Zeit damit verschwenden müssen, ‚mit dem Auge‘ zu scannen.

Wir werden diese drei ziemlich unterschiedlichen Aufgaben in SQL angehen

Wenn zwei Tabellen eine unterschiedliche Anzahl von Zeilen haben, können sie natürlich nicht gleich sein. Es gibt jedoch Zeiten, in denen Sie wissen müssen, ob Table_B alle Zeilen von Table_A ohne Unterschiede enthält. Wenn Sie mehr Details wünschen, möchten Sie vielleicht sogar die Zeilen in beiden Tabellen kennen, die nicht gemeinsam sind, oder die gemeinsamen Zeilen, wie durch den Primärschlüssel angegeben, die unterschiedlich waren. Warum nur zwei Tabellen vergleichen? Es gibt Möglichkeiten, so viele zu vergleichen, wie Sie benötigen. (wie zum Beispiel, wenn Sie die Metadaten in mehreren Datenbank-Snapshots vergleichen). Ja, es gibt viele Variationen

Sie haben Werkzeuge und Funktionen, um dieses Zeug zu tun, sicher?

Es gibt immer einen Platz für Tools wie SQL Data Compare, TableDiff, tSQLt oder Change Data Capture. Viel hängt von den Umständen und der Art der Aufgabe ab. Das Problem der Durchführung von Audits bei Änderungen an Daten in einem Live-System ist ein separates Thema, ebenso wie die Synchronisation von Tabellen und Datenbanken. Der Vergleich von XML-Dokumenten ist ebenfalls nicht möglich. Wir werden uns nur mit dem routinemäßigen Vergleich der Daten in Tabellen befassen

Ich verwende höchstwahrscheinlich TSQL-Techniken, um Tabellen zu vergleichen, wenn:

Entwickeln …

Im Zuge der Entwicklung einer Datenbank werden viele Tabellen verglichen. Es ist nicht nur das große Zeug: Jede tabellenwertige Funktion benötigt zum Beispiel einen Testbaum im Build-Skript, der sicherstellt, dass sie unter allen denkbaren Testumständen das tut, was Sie denken, und alle bösen Randfälle einbezieht, in denen es von den Testern in der Vergangenheit gefangen wurde. Jede gespeicherte Prozedur benötigt einen Test, um sicherzustellen, dass der Prozess, den sie ausführt, genau das tut, was beabsichtigt ist, und sonst nichts.

Es gab eine Zeit, in der die Build-Aktivität eher gemächlich war, aber wenn Sie einen nächtlichen Build- und Integrationstest haben, ist es am besten, ihn vollständig zu automatisieren und die lästige Arbeit loszuwerden.

ETL

Wenn Sie das Laden von Daten in ein System automatisieren, müssen Sie häufig verschiedene Bedingungen testen. Müssen Sie vorhandene Versionen der Zeilen aktualisieren und die neuen einfügen? Benötigen Sie eine Falle, um doppelte Einträge zu verhindern oder sogar vorhandene Einträge zu löschen?

Einrichten der Testdaten.

Die Skripte in diesem Artikel verwenden alle eine Tabelle aus der ehrwürdigen PUBS-Datenbank. Wir werden die Autoren-Tabelle verwenden, aber die Anzahl der Zeilen ein wenig auf 5000 erhöhen, um eine etwas realistischere Größe zu erhalten. Ich habe die Quelle für die Tabelle mit dem Artikel angegeben.

I then created a copy of the table …

1
2
3
4
5
6

SELECT * INTO authorsCopy
FROM authors
GO
ALTER TABLE dbo.authorsCopy ADD CONSTRAINT PK_authorsCopy PRIMARY KEY CLUSTERED
(au_id) ON PRIMARY
GO

Und dann einige der Zeilen geändert.

1
2
3
4

5

UPDATE authorsCopy SET address=“(Adresse,1,1,“)
WO au_ID IN (
WÄHLEN SIE TOP 10 au_id
VON authorsCopy f
Telefonisch BESTELLEN)

Jetzt sollten die beiden Tabellen mit ein paar kleinen Änderungen im Adressfeld überwiegend gleich sein

. um zu sehen, ob Tabellen unterschiedlich sind.

Manchmal möchte man nur wissen, ob Tabellen gleich sind. Ein Beispiel hierfür wäre die Überprüfung, ob eine TVF ordnungsgemäß funktioniert, indem ihr Ergebnis mit dem einer vorhandenen Tabelle mit den korrekten Ergebnissen verglichen wird. Der übliche Weg, dies zu tun, ist mit der CHECKSUM()Gruppe von Funktionen in SQL Server, weil sie sehr schnell sind.

Mit Prüfsummen

Sie können die BINARY_CHECKSUM Funktion verwenden, um zu überprüfen, ob Tabellen gleich sind: Nun, ungefähr gleich. Es ist schnell, aber es ist nicht perfekt, wie ich gleich demonstrieren werde. Wenn Sie eine Reihe von Tests haben, zum Beispiel ist es in der Regel ausreichend.

1
2
3
4

5

6
7
8
9
IF (
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
VON den Autoren)=(
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
VON authorsCopy)
WÄHLEN SIE ’sie sind wahrscheinlich gleich‘
SONST
WÄHLEN SIE ’sie sind anders‘

Damit dies funktioniert, darf Ihre Tabelle keinen TEXT, NTEXT, IMAGE or CURSOR (oder einen SQL_VARIANT mit einem dieser Typen) als Basistyp haben. Heutzutage wird dies immer seltener, aber wenn Sie irgendeine Komplikation haben, können Sie jede Spalte mit einem der nicht unterstützten Typen in einen unterstützten Typ zwingen. In der Praxis verwende ich im Allgemeinen eine Routine, die die Metadaten überprüft und dies automatisch ausführt, aber es ist nicht schön.

In einer funktionierenden Version möchten Sie wahrscheinlich die Liste der Spalten angeben, insbesondere wenn Sie eine explizite Erzwingung von Datentypen durchführen müssen oder wenn Sie nur bestimmte Spalten überprüfen,

Weder BINARY_CHECKSUM() noch seine einfache Schwester CHECKSUM() können Ihnen genau sagen, ob sich etwas in einer Zeile oder Tabelle geändert hat. Wir zeigen dies anhand der gebräuchlichen Wörter der englischen Sprache, die in einer Tabelle mit dem Namen CommonWords .. Sie würden erwarten, dass sie alle eine andere Prüfsumme haben, aber das ist nicht der Fall.

1
2
3
4

5

6
7
8
9
WÄHLEN SIE string, BINARY_CHECKSUM(string) ALS „Prüfsumme“
AUS commonWords
WHERE BINARY_CHECKSUM(string) IN
(
SELECT BINARY_CHECKSUM(string)
FROM commonwords
GRUPPIEREN NACH BINARY_CHECKSUM(string)
HAVING COUNT(*) > 2)
ORDER BY BINARY_CHECKSUM(string)

… das Ergebnis …

Bewaffnet mit diesen Informationen können wir schnell zeigen, dass verschiedene Strings die gleiche Prüfsumme haben können

1
2
3

WÄHLEN SIE BINARY_CHECKSUM(‚reed der Nerd‘),
BINARY_CHECKSUM(‚reed das Nest‘),
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‘)

….während…

1
2
3

SELECT BINARY_CHECKSUM(‚Das sieht dem nächsten sehr ähnlich‘),
BINARY_CHECKSUM(‚das sieht dem nächsten sehr ähnlich‘),
BINARY_CHECKSUM(‚Das sieht dem Nächsten sehr ähnlich‘)

… gibt Ihnen verschiedene Prüfsummen wie diese …

1
2

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

The sister function CHECKSUM()

1
2
3
4

SELECT CHECKSUM(‚This looks very much ‚),
CHECKSUM(‚das sieht sehr ähnlich aus wie das nächste‘),
CHECKSUM(‚Das sieht sehr ähnlich aus wie das Nächste‘)

… findet sie alle gleich, weil es die aktuelle Sortierung verwendet und meine Sortierung für die Datenbank die Groß- und Kleinschreibung nicht berücksichtigt. CHECKSUM() zielt darauf ab, Strings zu finden, die in der Prüfsumme gleich sind, wenn sie in einem String-Vergleich gleich sind.

1
2

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

Also, das Beste, was Sie sagen können, ist, dass es eine starke Wahrscheinlichkeit gibt, dass die Tabellen gleich sind, aber wenn Sie absolut sicher sein müssen, dann verwenden Sie einen anderen Algorithmus.

Wenn es Ihnen nichts ausmacht Unterschied im Fall in Textzeichenfolgen, dann können Sie CHECKSUM() anstelle von BINARY_CHECKSUM()

Der große Wert dieser Technik ist, dass, sobald Sie die Prüfsumme berechnet haben, die Sie benötigen, können Sie es als Wert in der Spalte einer Tabelle speichern, anstatt die ursprüngliche Tabelle zu benötigen und daher können Sie den gesamten Prozess noch schneller machen, und nehmen Sie weniger Zeit. Wenn Sie den von CHECKSUM() zurückgegebenen Prüfsummenwert speichern, stellen Sie sicher, dass Sie die Live-Tabelle mit einer Prüfsumme vergleichen, die mit derselben Sortierung generiert wurde.

Hier ist ein einfaches Beispiel für die ‚what’s changed‘-Routine.

1
2
3
4

5

6
7
8
9
10
11
12
13
14
15
– wir erstellen eine ‚checksum‘-Tabelle ‚on the fly‘ mit dem SELECT INTO .
SELECT
au_ID,
BINARY_CHECKSUM(au_id, au_lname, au_fname, phone, , city, , zip, ) AS
INTO auchk
FROM authorscopy
ORDER BY au_ID
/* Jetzt geben wir eine Einschränkung ein, um zu überprüfen, ob wir nicht im Lotto gewonnen haben (sehr unwahrscheinlich, aber nicht völlig unmöglich dass wir zwei Zeilen mit der gleichen Prüfsumme haben) */
ALTER TABLE AuChk ADD CONSTRAINT IsItUnique UNIQUE ()
UPDATE authorscopy SET au_fname=’Arthur‘
WHERE au_ID=’327-89-2366′
SELECT 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 VON 98949 1

Und dann räumen wir einfach auf.

1
2
3

/* und wir kehren einfach zu dem zurück, was es war, als Teil des Teardowns */
UPDATE authorscopy SET au_fname=’Arnold‘
WHERE au_ID=’327-89-2366′

Natürlich können Sie einen Trigger verwenden, aber manchmal möchten Sie nur einen täglichen oder wöchentlichen Bericht über Änderungen, ohne dass ein Trigger in eine Tabelle eindringt.

XML verwenden

Eine allgemeine Möglichkeit besteht darin, die XML-Version der beiden Tabellen zu vergleichen, da dies die Datentypübersetzung in Zeichenfolgen für Sie durchführt. Es ist langsamer als der Prüfsummenansatz, aber zuverlässiger.

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
SELECT ‚they are different‘

Hier können Sie die Art des Vergleichs angeben, indem Sie die Sortierung angeben.

oder Sie können dies tun, indem Sie Daten in Tabellen vergleichen ..

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)))
SELECT ‚they are pretty much the same‘
ELSE
SELECT ‚they are different‘ SELECT ‚they are different‘

… durch Berechnung einer Prüfsumme der XML-Version der Tabelle. Auf diese Weise können Sie die Prüfsumme der Tabelle speichern, mit der Sie vergleichen.

Finden, wo die Unterschiede in einer Tabelle sind

Die einfachste Aufgabe besteht darin, dass die Tabellen eine identische Anzahl von Zeilen und eine identische Tabellenstruktur haben. Manchmal möchten Sie wissen, welche Zeilen unterschiedlich sind und welche fehlen. Sie müssen natürlich angeben, was Sie mit ‚gleich‘ meinen, insbesondere wenn die beiden Tabellen unterschiedliche Spalten haben. Die Methode, die Sie für den Vergleich auswählen, wird im Allgemeinen durch diese Details bestimmt.

Die UNION ALL … GROUP BY-Technik

Der klassische Ansatz zum Vergleichen von Tabellen besteht darin, eine UNION ALL für die SELECT Anweisungen zu verwenden, die die Spalten enthalten, die Sie vergleichen möchten, und dann GROUP BY diese Spalten. Damit dies funktioniert, muss natürlich eine Spalte mit eindeutigen Werten in GROUP BY vorhanden sein, und der Primärschlüssel ist dafür ideal. Keine der beiden Tabellen darf dupliziert werden. Wenn sie eine unterschiedliche Anzahl von Zeilen haben, werden diese als Unterschiede angezeigt.

1
2
3
4

5

6
7
8
9
10
11
12
13
(
WÄHLEN SIE au_ID
AUS dem
(
WÄHLEN SIE au_id, au_lname, au_fname, Telefon, Adresse, Stadt, Bundesland, Postleitzahl, Vertrag
VON Autoren
UNION ALLE
WÄHLEN SIE au_id, au_lname, au_fname, Telefon, Adresse, Stadt, Bundesland, Postleitzahl, Vertrag
VON authorsCopy) BothOfEm
GRUPPE VON au_id, au_lname, au_fname, Telefon, Adresse, Stadt, Bundesland, Postleitzahl, Vertrag
HAVING COUNT(*)<2) f

Wenn eine der Tabellen ein Duplikat hat, dann wird es Ihnen ein falsches Ergebnis geben, wie hier, wo Sie zwei Tabellen haben, die sehr unterschiedlich sind und das Ergebnis sagt Ihnen, dass sie gleich sind! Aus diesem Grund ist es eine gute Idee, die Spalte (n) einzuschließen, die den Primärschlüssel bilden, und die Zeilen nur einmal einzuschließen!

1
2
3
4

5

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
WÄHLEN SIE COUNT(*), Address_ID,TheAddress,ThePostCode
Address_ID,TheAddress,ThePostCode
VON
(
WERTE
(9, ‚929 Augustine lane, Staple Hill Ward South Gloucestershire UK‘,’BS16 4LL‘),
(10, ’45 Bradfield road, Parwich Derbyshire UK‘,’DE6 1QN‘)
) TableA(Address_ID, Die Adresse,die Postleitzahl)
UNION ALL
SELECT Address_ID,Die Adresse,die Postleitzahl
FROM
(
VALUES
(8, „‚The 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

TheCount Address_ID TheAddress ThePostCode
———– ———– ————————- ————
(0 Zeile(n) betroffen)

Die Technik kann zum Vergleichen von mehr als zwei Tabellen verwendet werden. Sie müssen nur UNION ALL die Tabellen, die Sie vergleichen müssen, und ändern Sie die HAVING Klausel, um nur die Zeilen zu filtern, die nicht in allen Tabellen enthalten sind.

Mit EXCEPT

können Sie jetzt das viel sauberere und etwas schnellere EXCEPT .

1
2
3

SELECT * from authors
EXCEPT
SELECT * from authorsCopy

Hier werden alle Zeilen in authors angezeigt, die in authorsCopy nicht gefunden wurden. Wenn sie gleich sind, würde es keine Zeilen zurückgeben

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

au_id au_lname au_fname Telefon Adresse Stadt plz Vertrag
———– ———– ——— ———— ————————– ———– —– —– ——–
041-76-1076 Sosa Sonja 000-198-8753 29 Second Avenue Omaha CT 23243 0
187-42-2491 Mc Connell Trenton 0003090766 279 Den Haag Weg 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 Grün Milton Antrieb Norfolk WA 69949 1
697-84-0401 Montes Leanne 000-018-0454 441 East Oak Parkway San Antonio MD 38169 1
727-35-9948 Lange Jonathon 000-8761152 280 Nobel Avenue Anchorage LA NULL 1
875-54-8676 Stein Keisha 000-107-1947 763 Weiß Fabien Way Fremont ND 08520 0
884-64-5876 Keller Steven 000-2787554 45 Weiß Nobel Boulevard Milwaukee NY 29108 1
886-75-9197 Ellis Marie 001032-5109 35 Osten Zweite Boulevard Chicago IL 32390 1
975-80-3567 Salazar Johanna 001-028-0716 17 New Boulevard Jackson ND 71625 0
(10 Zeile(n) betroffen)

Ich verwende SELECT * nur, um die Dinge für den Artikel einfach zu halten. Normalerweise listen Sie alle Spalten auf, die Sie vergleichen möchten.

Dies funktioniert nur für Tabellen mit der gleichen Anzahl von Zeilen, da, wenn Autoren zusätzliche Zeilen hätten, es immer noch sagen würde, dass sie anders waren, da die Zeilen in Autoren, die nicht in authorsCopy waren, zurückgegeben würden. Dies liegt daran, dass EXCEPT alle eindeutigen Werte aus der Abfrage links vom EXCEPT Operanden zurückgibt, die nicht auch aus der Abfrage rechts gefunden werden

Dies zeigt hoffentlich, was ich meine

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

WÄHLEN SIE Address_ID,TheAddress,ThePostCode
AUS
(WERTE
(9, ‚929 Augustine lane, Staple Hill Ward South Gloucestershire UK‘,’BS16 4LL‘),
(10, ’45 Bradfield road, Parwich Derbyshire UK‘,’DE6 1QN‘)
) TableA(Address_ID,TheAddress,
EXCEPT
SELECT Address_ID,TheAddress,ThePostCode from
(VALUES
(8, „‚Die Pippins“, 20 Gloucester Pl, Chirton Ward, Tyne & ‚ UK‘,’NE29 7AD‘),
(8, „‚Die Pippins“,‘ , 20 Gloucester Pl, Chirton Gemeinde, 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 Die Postleitzahl
———– ———————————————- ———–
(0 Zeile(n) betroffen)

…während …

1
2
3
4

5

6
7
8
9
10
11
12
13
14
Address_ID,TheAddress,ThePostCode VON
(WERTE
(8, „‚Die Pippins“, 20 Gloucester Pl, Chirton Ward, Tyne & ‚ UK‘,’NE29 7AD‘),
(8, „‚Die Pippins“, 20 Gloucester Pl, Chirton Ward, Tyne & “ UK‘,’NE29 7AD‘),
(9, ‚929 Augustine lane, Staple Hill Ward South Gloucestershire Vereinigtes Königreich‘,’BS16 4LL‘),
(10, ’45 Bradfield road, Parwich Derbyshire Vereinigtes Königreich‘,’DE6 1QN‘)
) TableB(Address_ID,TheAddress,ThePostCode )
EXCEPT
SELECT Address_ID,TheAddress,ThePostCode
VON
(WERTE
(9, ‚929 Augustine lane, Staple Hill Ward South Gloucestershire UK‘,’BS16 4LL‘),
(10, ’45 Bradfield road, Parwich Derbyshire UK‘,’DE6 1QN‘)
) TableA(Address_ID,TheAddress,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)

Diese Funktion von EXCEPT kann vorteilhaft verwendet werden, wenn Sie insbesondere überprüfen möchten, ob TableA in TableB enthalten ist. Wenn die Tabellen also eine unterschiedliche Anzahl von Zeilen haben, können Sie sie trotzdem vergleichen.

Möglicherweise möchten Sie nicht alle Spalten vergleichen. Sie sollten immer die Spalten angeben, die Sie vergleichen möchten, um die Gleichheit zu bestimmen. Wenn Sie beispielsweise nur die Adresse vergleichen möchten, verwenden Sie …

1
2
3

Adresse VON Autoren AUSWÄHLEN
AUßER
Adresse VON authorsCopy AUSWÄHLEN

Die Outer-Join-Technik

Es ist auch die Technik der äußeren Verbindung. Dies ist eine allgemeinere Technik, die Ihnen zusätzliche Einrichtungen bietet. Wenn Sie beispielsweise den vollständigen äußeren Join verwenden, können Sie die nicht übereinstimmenden Zeilen in beiden Tabellen abrufen. Dadurch erhalten Sie eine Vorher-Nachher-Ansicht der Änderungen in den Daten. Es wird allgemeiner in der Synchronisation verwendet, um Ihnen mitzuteilen, welche Zeilen gelöscht, eingefügt und aktualisiert werden sollen.

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.vertrag
VON Autoren
LEFT OUTER JOIN authorsCopy
AUF authors.au_ID = AuthorsCopy.au_ID
UND authors.au_lname =authorsCopy.au_lname
UND authors.au_fname =authorsCopy.au_fname
UND Autoren.telefon =authorsCopy.telefon
UND COALESCE(Autoren.adresse,“)=COALESCE(authorsCopy.adresse,“)
UND COALESCE(Autoren.stadt,“) =COALESCE(authorsCopy.stadt,“)
UND VERSCHMELZEN(Autoren.zustand,“) =COALESCE(authorsCopy.zustand,“)
UND VERSCHMELZEN(Autoren.zip,“) =COALESCE(authorsCopy.zip,“)
UND Autoren.vertrag =authorsCopy.contract
WHERE authorsCopy.au_ID IS NULL

Wie Sie sehen können, gibt es bei diesem Ansatz Schwierigkeiten mit Nullspalten, aber er ist so schnell wie die anderen und bietet Ihnen mehr Vielseitigkeit für Ihre Vergleiche.

Lokalisieren der Unterschiede zwischen Tabellen

Möglicherweise benötigen Sie eine schnelle Möglichkeit zu sehen, welche Spalte und Zeile sich geändert hat. Ein sehr genialer Weg, dies zu tun, wurde kürzlich veröffentlicht. Es verwendete XML. ‚Vergleichen Sie Tabellen und melden Sie die Unterschiede, indem Sie XML verwenden, um die Daten zu drehen‘ (Anmerkung der Redaktion: Link veraltet). Es ist klug, aber zu langsam. Das Gleiche kann rein in SQL gemacht werden. Grundsätzlich führen Sie einen spaltenweisen Vergleich von Daten basierend auf dem Primärschlüssel unter Verwendung eines Schlüssel / Wert-Paares durch. Wenn Sie die gesamte Tabelle auf einmal ausführen, ist dies ziemlich langsam: Der beste Trick besteht darin, dies nur in den Zeilen zu tun, in denen Sie wissen, dass es einen Unterschied gibt.

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
temp TABLE(au_id VARCHAR(11) PRIMARY KEY) /*Dies enthält die Primärschlüssel von Zeilen, die sich geändert haben */
INSERT INTO @Temp(au_ID) –determine which rows have changed
SELECT au_ID
FROM –use the EXCEPT technique qwas in unseren Tests die schnellste ist
(
SELECT au_id, au_lname, au_fname, phone, , city, state, zip,
FROM ,
EXCEPT
SELECT au_id, telefon, adresse, Stadt, bundesland, Postleitzahl, Vertrag
VON authorsCopy
)f–jetzt wählen wir nur die Spalten aus, die sich geändert haben
SELECT lefthand.au_id,lefthand.name ,lefthand.wert WIE original,Righthand.wert ALS geändert
VON (–jetzt legen wir einfach die beiden Tabellen als Schlüsselwertpaare an und verwenden die Zeichenfolgenversionen der Daten
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
WÄHLEN SIE authors.au_id, ‚phone‘,phone
FROM authors INNER JOIN @Temp altered ON altered AUS.au_id=authors.au_id
UNION
WÄHLEN SIE authors.au_id, ‚adresse‘,Adresse
VON authors INNER JOIN @Temp altered AUF altered.au_id=authors.au_id
UNION
WÄHLEN SIE authors.au_id, ‚Stadt‘ ALS ’name‘, Stadt ALS ‚Wert‘
VON authors INNER JOIN @Temp altered AUF altered.au_id= >

UNION
SELECT authors.au_id, ‚State‘,state
FROM authors INNER JOIN @Temp altered ON altered.au_id=authors.au_id
UNION
Autoren AUSWÄHLEN.au_id, ‚zip‘,zip
VON Autoren INNER JOIN @Temp geändert AUF altered.au_id=authors.au_id
UNION
SELECT authors.au_id, ‚contract‘,CONVERT(CHAR(1),contract)
VON Autoren INNER JOIN @Temp geändert AUF altered.au_id=authors.au_id) LeftHand
INNER JOIN (
SELECT authorsCopy.au_id , ‚au_lname‘ ALS ’name‘,au_lname ALS ‚Wert‘
VON authorsCopy INNER JOIN @Temp geändert AUF altered.au_id=authorsCopy.au_id
UNION
SELECT authorsCopy.au_id, ‚au_fname‘,au_fname
VON authorsCopy INNER JOIN @Temp geändert AUF altered.au_id=authorsCopy.au_id
UNION
SELECT authorsCopy.au_id, ‚phone‘,phone
VON authorsCopy INNER JOIN @Temp geändert AUF altered.au_id=authorsCopy.au_id
UNION
SELECT authorsCopy. au_id, ‚adresse‘,Adresse
VON authorsCopy INNER JOIN @Temp geändert AUF altered.au_id=authorsCopy.au_id
UNION
SELECT authorsCopy.au_id, ‚Stadt‘ ALS ’name‘,Stadt ALS ‚Wert‘
VON authorsCopy INNER JOIN @Temp altered AUF altered.au_id=authorsCopy.au_id
UNION
WÄHLEN SIE authorsCopy.au_id, ‚State‘,state
VON authorsCopy INNER JOIN @Temp altered AUF altered.au_id=authorsCopy.au_id
UNION
WÄHLEN SIE authorsCopy. au_id, ‚zip‘,zip
VON authorsCopy INNER JOIN @Temp geändert AUF altered.au_id=authorsCopy.au_id
UNION
WÄHLEN SIE authorsCopy.au_id, ‚contract‘,CONVERT(CHAR(1),contract)
VON authorsCopy INNER JOIN @Temp geändert AUF altered.au_id=authorsCopy.au_id) rightHand
AUF lefthand.au_ID=righthand.au_ID
UND lefthand.name=righthand.name
WOBEI lefthand.wert<>rechte Hand.wert

In unserem Beispiel würde dies ergeben:

1
2
3
4

5

6
7
8
9
10
11
12
———– ——– —————————- ————————————
041-76-1076 Adresse 29 Second Avenue 9 Second Avenue
187-42-2491 Adresse 279 Haager Weg 79 Haager Weg
220-43-7067 Adresse 269 East Hague Street 69 East Hague Street
505-28-2848 Adresse 73 Green Milton Drive 3 Green Milton Drive
697-84-0401 Adresse 441 East Oak Parkway 41 East Oak Parkway
727-35-9948 Adresse 280 Nobel Avenue 80 Nobel Avenue
875-54-8676 Adresse 763 White Fabien Way 63 White Fabien Way
884-64-5876 Adresse 45 White Nobel Boulevard 5 White Nobel Boulevard
886-75-9197 Adresse 35 East Second Boulevard 5 East Second Boulevard
975-80-3567 Adresse 17 Neuer Boulevard 7 Neuer Boulevard

Diese Technik dreht die Zeilen der Tabellen, die Unterschiede aufweisen, in eine EAV-Tabelle (Entity-Attribute-Value), sodass Unterschiede innerhalb einer Zeile verglichen und angezeigt werden können. Es führt diese Rotation durch, indem UNIONden Namen und den String-Wert jeder Spalte eingibt. Diese Technik funktioniert am besten, wenn es nicht viele Unterschiede gibt.

Schlussfolgerungen

Es gibt keine einzige ideale Methode, um die Daten in Tabellen oder Ergebnissen zu vergleichen. Eine von mehreren Techniken wird für eine bestimmte Aufgabe am relevantesten sein. Es hängt alles von genau den Antworten ab, die Sie benötigen, und von der Art der Aufgabe. Benötigen Sie eine schnelle Überprüfung, ob sich eine Tabelle nicht geändert hat, oder müssen Sie genau wissen, um welche Änderungen es sich handelt? SQL ist natürlich schnell bei dieser Aufgabe und Vergleiche von Tabellen und Ergebnissen ist eine vertraute Aufgabe für viele Datenbankentwickler.

Wenn es eine allgemeine Regel gibt, würde ich sagen, dass explorative oder Ad-hoc-Arbeit ein Tool wie SQL Data Compare benötigt, während ein Routineprozess innerhalb der Datenbank eine handgeschnittene SQL-Technik erfordert.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.