Les deux réponses ont des possibilités. Juste pour développer un peu vos options ..
Option 1
SI mySQL prend en charge une sorte de hachage, sur une base par ligne , vous pouvez utiliser une variante de la suggestion de comodoro pour éviter les suppressions définitives.
Identifier la modification
Pour identifier les modifications, effectuez une jointure interne sur la clé primaire et vérifiez les valeurs de hachage. S'ils sont différents, le produit a été modifié et doit être mis à jour :
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
Identifier supprimé
Utilisez une jointure externe simple pour identifier les enregistrements qui n'existent pas dans la table temporaire et les marquer comme "supprimés"
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
Identifier le nouveau
Enfin, utilisez une jointure externe similaire pour insérer tout "nouveau" produit.
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
Option 2
Si le hachage par ligne n'est pas possible, une approche alternative est une variante de la suggestion de Sharondio .
Ajoutez une colonne "statut" à la table temporaire et marquez tous les enregistrements importés comme "nouveau", "modifié" ou "inchangé" via une série de jointures. (La valeur par défaut doit être "modifiée").
Identifier UN-Changed
Utilisez d'abord une jointure interne, sur tous les champs, pour identifier les produits qui n'ont PAS changé. (Remarque, si votre table contient des champs nullables, n'oubliez pas d'utiliser quelque chose comme coalesce
Sinon, les résultats peuvent être faussés car null
les valeurs ne sont égales à rien.
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
...
Identifier le nouveau
Comme précédemment, utilisez une jointure externe pour identifier les "nouveaux" enregistrements.
UPDATE Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'New'
WHERE p.ProductID IS NULL
Par processus d'élimination, tous les autres enregistrements de la table temporaire sont "modifiés". Une fois que vous avez calculé les statuts, vous pouvez mettre à jour la table Produits :
/* 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