Kedua tanggapan memiliki kemungkinan. Hanya untuk sedikit memperluas opsi Anda ..
Opsi #1
JIKA mySQL mendukung semacam hashing, berdasarkan per baris , Anda dapat menggunakan variasi saran comodoro untuk menghindari penghapusan permanen.
Identifikasi Berubah
Untuk mengidentifikasi perubahan, lakukan penggabungan dalam pada kunci utama dan periksa nilai hash. Jika berbeda, produk diubah dan harus diperbarui:
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
Identifikasi Dihapus
Gunakan gabungan luar sederhana untuk mengidentifikasi catatan yang tidak ada di tabel sementara, dan tandai sebagai "dihapus"
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
Identifikasi Baru
Terakhir, gunakan gabungan luar yang serupa untuk menyisipkan produk "baru".
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
Opsi #2
Jika hashing per baris tidak memungkinkan, pendekatan alternatif adalah variasi dari saran Sharondio .
Tambahkan kolom "status" ke tabel temp dan tandai semua catatan yang diimpor sebagai "baru", "berubah" atau "tidak berubah" melalui serangkaian gabungan. (Defaultnya harus "diubah").
Identifikasi UN-Changed
Pertama gunakan gabungan dalam, di semua bidang, untuk mengidentifikasi produk yang TIDAK berubah. (Perhatikan, jika tabel Anda berisi bidang yang dapat dibatalkan, ingatlah untuk menggunakan sesuatu seperti coalesce
Jika tidak, hasilnya mungkin miring karena null
nilai tidak sama dengan apa pun.
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
...
Identifikasi Baru
Seperti sebelumnya, gunakan gabungan luar untuk mengidentifikasi catatan "baru".
UPDATE Products_Temp tmp LEFT JOIN Products p ON tmp.ProductID = p.ProductID
SET tmp.Status = 'New'
WHERE p.ProductID IS NULL
Dengan proses eliminasi, semua catatan lain di tabel temp "diubah". Setelah menghitung status, Anda dapat memperbarui tabel Produk:
/* 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