Obie odpowiedzi mają możliwości. Po prostu trochę poszerzę swoje opcje ..
Opcja nr 1
JEŚLI mySQL obsługuje pewien rodzaj haszowania, na podstawie wiersza , możesz użyć odmiany sugestii Comodoro aby uniknąć twardego usunięcia.
Zidentyfikuj zmienione
Aby zidentyfikować zmiany, wykonaj sprzężenie wewnętrzne na kluczu podstawowym i sprawdź wartości skrótu. Jeśli są różne, produkt został zmieniony i powinien zostać zaktualizowany:
UPDATE Products p INNER JOIN Products_Temp tmp ON tmp.ProductID = p.ProductID
SET p.ProductName = tmp.ProductName
, p.Stock = tmp.Stock
, ...
, p.DateLastChanged = now()
, p.IsDiscontinued = 0
WHERE tmp.TheRowHash <> p.TheRowHash
Zidentyfikuj usunięte
Użyj prostego sprzężenia zewnętrznego, aby zidentyfikować rekordy, które nie istnieją w tabeli tymczasowej, i oflaguj je jako „usunięte”
UPDATE Products p LEFT JOIN Products_Temp tmp ON tmp.ProductID = p.ProductID
SET p.DateLastChanged = now()
, p.IsDiscontinued = 1
WHERE tmp.ProductID IS NULL
Zidentyfikuj nowy
Na koniec użyj podobnego połączenia zewnętrznego, aby wstawić wszelkie „nowe” produkty.
INSERT INTO Products ( ProductName, Stock, DateLastChanged, IsDiscontinued, .. )
SELECT tmp.ProductName, tmp.Stock, now() AS DateLastChanged, 0 AS IsDiscontinued, ...
FROM Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
WHERE p.ProductID IS NULL
Opcja nr 2
Jeśli haszowanie na wiersz nie jest możliwe, alternatywnym podejściem jest odmiana sugestia Sharondio .
Dodaj kolumnę „status” do tabeli tymczasowej i oznacz wszystkie importowane rekordy jako „nowe”, „zmienione” lub „niezmienione” za pomocą serii złączeń. (Domyślnie powinno być „zmienione”).
Zidentyfikuj niezmienione
Najpierw użyj sprzężenia wewnętrznego we wszystkich polach, aby zidentyfikować produkty, które NIE uległy zmianie. (Pamiętaj, że jeśli Twoja tabela zawiera pola dopuszczające wartość null, pamiętaj, aby użyć czegoś takiego jak coalesce
W przeciwnym razie wyniki mogą być przekrzywione, ponieważ null
wartości nie są równe niczemu.
UPDATE Products_Temp tmp INNER JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'Unchanged'
WHERE p.ProductName = tmp.ProductName
AND p.Stock = tmp.Stock
...
Zidentyfikuj nowy
Podobnie jak poprzednio, użyj sprzężenia zewnętrznego, aby zidentyfikować „nowe” rekordy.
UPDATE Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'New'
WHERE p.ProductID IS NULL
W procesie eliminacji wszystkie inne rekordy w tabeli tymczasowej są „zmieniane”. Po obliczeniu stanów możesz zaktualizować tabelę Produkty:
/* update changed products */
UPDATE Products p INNER JOIN Products_Temp tmp ON tmp.ProductID = p.ProductID
SET p.ProductName = tmp.ProductName
, p.Stock = tmp.Stock
, ...
, p.DateLastChanged = now()
, p.IsDiscontinued = 0
WHERE tmp.status = 'Changed'
/* insert new products */
INSERT INTO Products ( ProductName, Stock, DateLastChanged, IsDiscontinued, .. )
SELECT tmp.ProductName, tmp.Stock, now() AS DateLastChanged, 0 AS IsDiscontinued, ...
FROM Products_Temp tmp
WHERE tmp.Status = 'New'
/* flag deleted records */
UPDATE Products p LEFT JOIN Products_Temp tmp ON tmp.ProductID = p.ProductID
SET p.DateLastChanged = now()
, p.IsDiscontinued = 1
WHERE tmp.ProductID IS NULL