И двата отговора имат възможности. Само да разширя малко опциите си...
Опция №1
АКО mySQL поддържа някакъв вид хеширане, на база на ред , можете да използвате вариант на предложение на comodoro за да избегнете твърди изтривания.
Идентифициране на променено
За да идентифицирате промените, направете вътрешно присъединяване на първичния ключ и проверете хеш стойностите. Ако са различни, продуктът е променен и трябва да бъде актуализиран:
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
Идентифициране на изтрито
Използвайте просто външно свързване, за да идентифицирате записи, които не съществуват във временната таблица, и ги маркирайте като „изтрити“
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
Идентифициране на ново
И накрая, използвайте подобно външно съединение, за да вмъкнете всякакви „нови“ продукти.
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
Опция №2
Ако хеширането на ред не е осъществимо, алтернативен подход е вариант на предложението на Sharondio .
Добавете колона "status" към временната таблица и маркирайте всички импортирани записи като "нови", "променени" или "непроменени" чрез поредица от обединения. (По подразбиране трябва да бъде "променено").
Идентифициране на UN-променено
Първо използвайте вътрешно присъединяване във всички полета, за да идентифицирате продукти, които НЕ са се променили. (Обърнете внимание, ако таблицата ви съдържа полета с нулеви стойности, не забравяйте да използвате нещо като coalesce
В противен случай резултатите може да бъдат изкривени, защото null
стойностите не са равни на нищо.
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
...
Идентифициране на ново
Както преди, използвайте външно присъединяване, за да идентифицирате "нови" записи.
UPDATE Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'New'
WHERE p.ProductID IS NULL
Чрез процеса на елиминиране всички други записи във временната таблица се "променят". След като изчислите статусите, можете да актуализирате таблицата с продукти:
/* 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