Entrambe le risposte hanno delle possibilità. Solo per ampliare un po' le tue opzioni..
Opzione n. 1
SE mySQL supporta una sorta di hashing, su base per riga , potresti utilizzare una variante del suggerimento di comodoro per evitare eliminazioni forzate.
Identifica modificato
Per identificare le modifiche, esegui un inner join sulla chiave primaria e controlla i valori hash. Se sono diversi, il prodotto è stato modificato e dovrebbe essere aggiornato:
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
Identifica eliminati
Usa un semplice outer join per identificare i record che non esistono nella tabella temporanea e contrassegnarli come "eliminati"
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
Identifica nuovo
Infine, utilizzare un join esterno simile per inserire eventuali "nuovi" prodotti.
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
Opzione n. 2
Se l'hashing per riga non è fattibile, un approccio alternativo è una variazione del suggerimento di Sharondio .
Aggiungi una colonna "stato" alla tabella temporanea e contrassegna tutti i record importati come "nuovi", "modificati" o "non modificati" tramite una serie di join. (L'impostazione predefinita dovrebbe essere "modificata").
Identifica UN-Cambiato
Per prima cosa usa un inner join, su tutti i campi, per identificare i prodotti che NON sono cambiati. (Nota, se la tua tabella contiene campi nullable, ricorda di usare qualcosa come coalesce
In caso contrario, i risultati potrebbero essere distorti perché null
i valori non sono uguali a niente.
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
...
Identifica nuovo
Come prima, usa un outer join per identificare i "nuovi" record.
UPDATE Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'New'
WHERE p.ProductID IS NULL
Con il processo di eliminazione, tutti gli altri record nella tabella temporanea vengono "modificati". Una volta calcolati gli stati, puoi aggiornare la tabella Prodotti:
/* 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