Ich habe ein System Integrationsprojekt, CRUD von einem DB zu einem anderen benötigt. Nicht besonders kompliziert. Wenn es jedoch darum geht, Zeilen zu löschen, die im Ziel vorhanden sind, aber nicht in der Quelle, stieß ich auf ein kleines Problem. Zu den Standardmustern gehören: LINKE VERBINDUNG, NICHT VORHANDEN oder NICHT IN. Ich wählte die LINKE VERBINDUNG. Meine 'Telefon'-Tabelle verwendet einen zusammengesetzten Schlüssel, Mitarbeiter-ID' und den PhoneType: Arbeit, Privat, Mobil usw. Der Standard-Link-Join löscht JEDE Ziel-Telefonnummer, die NICHT in der Quelle enthalten ist. Dies löscht die gesamte Tabelle. HINWEIS: Ich aktualisiere nur Datensätze, die seit der letzten Aktualisierung geändert wurden, NICHT das gesamte Ziel & Quelle. Also schrieb ich ein Update, das ich wirklich schlecht SQL vermuten:SQL Löschen, wo nicht mit zusammengesetzten Schlüssel
-- SOURCE
DECLARE @tmpPhones TABLE(Id varchar(8), PhoneType int, PhoneNumber varchar(30), PRIMARY KEY (Id, PhoneType))
INSERT into @tmpPhones values
('TEST123', 1, '12345678'),
('TEST123', 2, '12345678'),
('TEST123', 3, '12345678')
-- TARGET
[email protected] TABLE(Id varchar(8), PhoneType int, PhoneNumber varchar(30), PRIMARY KEY (Id, PhoneType))
INSERT into @Phone values
('TEST123', 1, '12345678'), <-- Exists in both, leave
('TEST123', 2, '12345678'), <-- Exists in both, leave
('TEST123', 3, '12345678'), <-- Exists in both, leave
('TEST123', 4, '12345678'), <-- ONLY delete this one!
('TEST456', 2, '12345678'), <-- Ignore this employee Id
('TEST456', 3, '12345678'), ""
('TEST456', 4, '12345678') ""
DELETE p
FROM @Phone p
LEFT JOIN @tmpPhones t
ON t.Id = p.Id AND t.PhoneType = p.PhoneType
WHERE t.Id IS NULL AND t.PhoneType IS NULL
AND p.Id IN (SELECT Id FROM @tmpPhones) <-- a sad hack?
Dies funktioniert, aber ich fühle mich wie es eine bessere Art und Weise ist sicherzustellen, dass wir nur Datensätze für diese Mitarbeiter zu löschen, die nicht alle der andere.
Irgendwelche Vorschläge?
ist dieser SQL Server? – Nikki9696
Ja, SQL Server 2012. –
LINKER JOIN ist hier völlig falsch – wildplasser