這是我的第一個堆棧溢出文章!社區一直在幫助很大!如何解決存儲過程中沒有「LOAD DATA」支持和/或MySQL中TRANSACTION中缺少EXIT HANDLER的問題?
我有一個90K排CSV我試圖插入表,通過一個臨時表,CSV,如:
CREATE TEMPORARY TABLE temp_product like product;
LOAD DATA LOCAL INFILE "myfile.csv"
...
但我想包插件和一些額外的
CREATE PROCEDURE update_products()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK;
START TRANSACTION;
....
我喜歡這種方法,因爲它允許在遇到任何錯誤,我自動回滾,而且包裝:通過一個過程,其中包含了交易,並退出處理櫃面出現任何故障,或者拋出一個警告操作很好地處理整個邏輯塊的交易。唉:
Error : LOAD DATA is not allowed in stored procedures
(我不能肯定這是爲什麼我想這只是目前還不支持?)我不能肯定我的語法正確(或如果這甚至有可能),但我甚至會沒事喜歡的東西:
DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK;
START TRANSACTION;
但是,這將引發明顯的語法錯誤:
Error : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK' at line 1
看來我可以做這個工作,如果我能以不同的方式加載CSV,但我可能會失去做我的速度批量插入,和/或必須使用基於磁盤的表格,因爲我可能需要與其建立多個連接。據我所知,臨時表只存在於單個連接/事務中,而且我不能100%確定MySQL客戶端navicat如何管理它。
我也不反對用PHP包裝這一切,如果這是最有道理的方式來管理一個腳本,該腳本在與LOAD DATA
交易時出現錯誤/警告時會自動回滾。
隨意告訴我,我接近這完全錯了。我覺得可能有更聰明的方式來做我正在做的事情。
這是一個很好的觀點,謝謝。由於臨時表無論如何都是易失性/非永久性的,因此它可能不需要成爲交易的一部分。我想我擔心臨時表會在事務運行之前消失。只要兩個操作都在同一個連接中進行(即沒有超時),應該沒問題,是的?我想我需要爲我的MySQL客戶端提供RTFM,以瞭解它如何處理連接。 – Andrew
@Andrew只要你使用相同的連接,臨時表應該在那裏。當然,如果臨時表成爲問題,您可以隨時寫入一張真正的表格。 –
我曾經考慮過創建一個基於磁盤的表,以便稍後像您提到的那樣刪除它,但是計算出的開銷會有點多。我想我會做一些基準測試,看看會發生什麼。 – Andrew