Beide reacties hebben mogelijkheden. Gewoon om je opties een beetje uit te breiden ..
Optie #1
ALS mySQL ondersteunt een soort hashing, per rij , kunt u een variant van comodoro's suggestie gebruiken om harde verwijderingen te voorkomen.
Gewijzigd identificeren
Om wijzigingen te identificeren, voert u een inner join uit op de primaire sleutel en controleert u de hash-waarden. Als ze anders zijn, is het product gewijzigd en moet het worden bijgewerkt:
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
Identificeer verwijderd
Gebruik een eenvoudige outer join om records te identificeren die niet in de tijdelijke tabel voorkomen en markeer ze als "verwijderd"
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
Identificeer nieuw
Gebruik ten slotte een vergelijkbare outer join om eventuele "nieuwe" producten in te voegen.
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
Optie #2
Als hashing per rij niet mogelijk is, is een alternatieve benadering een variatie op Sharondio's suggestie .
Voeg een "status"-kolom toe aan de tijdelijke tabel en markeer alle geïmporteerde records als "nieuw", "gewijzigd" of "ongewijzigd" via een reeks joins. (De standaardinstelling moet "gewijzigd" zijn).
Identificeer UN-gewijzigd
Gebruik eerst een inner join, op alle velden, om producten te identificeren die NIET zijn gewijzigd. (Let op, als uw tabel velden bevat die null kunnen bevatten, vergeet dan niet iets als coalesce
te gebruiken Anders kunnen de resultaten vertekend zijn omdat null
waarden zijn nergens gelijk aan.
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
...
Identificeer nieuw
Gebruik zoals eerder een outer join om 'nieuwe' records te identificeren.
UPDATE Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'New'
WHERE p.ProductID IS NULL
Door eliminatieproces worden alle andere records in de tijdelijke tabel "gewijzigd". Nadat u de statussen heeft berekend, kunt u de tabel Producten bijwerken:
/* 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