2013-02-11 259 views
1

我想加快將非常大的xml文件導入到我的mysql數據庫中,我決定將所有查詢轉儲到SQL文件中,並在控制檯上執行它,位更快。在SQL文件中使用IF控制INSERT和UPDATE查詢

但我的問題是,我不能簡單地插入所有的數據。

某些表格被鏈接,這就是爲什麼我不能使用非常快的LOAD DATA INFILE功能。所以我想把查詢放在一個SQL文件中,但我需要一些控制操作。

我有一個數據集,我需要它的ID(作爲主鍵),以便能夠使用該ID在另一個表中添加數據。

所以我通過mysql的控制檯嘗試是這樣的:

INSERT IGNORE INTO tableA VALUES (A, B, C); 
SET @id = LAST_INSERT_ID(); 
IF(@id, SELECT 1, SELECT id INTO @id FROM tableA WHERE a=A and b=B and c=C); 
INSERT INTO tableB VALUES (@id, B, C); 

顯然IF語句不起作用,它僅適用於 「SELECT IF」。

我試圖做的是使用INSERT IGNORE將數據集添加到tableA中,因此忽略重複的錯誤。如果它添加一個新行,我得到我的@id與LAST_INSERT_ID(),如果有一個重複的@id是空的,但與我的IF檢查我選擇,重複並把它INTO @A,所以無論如何我有@id設置。那麼我使用@id將我的數據放入tableB,所以我有正確的鏈接。

有沒有可能用IF做這個工作流程?由於我無法創建一個簡單的CSV來使用LOAD DATA INFILE,因爲我需要對其進行一些檢查,所以我認爲生成SQL是最好的。

我的XML文件就像20-25GB大。我的perl腳本工作了3周,將數據導入到數據庫中進行所有檢查,但由於我所做的所有mysql查詢都非常緩慢,我想將所有查詢放在一個文件中並一次性放入數據庫。如果我能控制我的查詢流程,我可以創建那個大的sql文件,而不是使用我的perl腳本中的所有檢查運行數百萬個查詢。

請告訴我,這是可能的。

回答

1

我不確定你需要這樣做。如果tableA.atableA.b,並tableA.c都決定tableA.id,則不管行項目是否成功與否,你應該能夠做到:

INSERT IGNORE INTO tableA VALUES (A, B, C); 
INSERT INTO tableB SELECT id, B, C FROM tableA WHERE a=A AND b=B AND c=C; 

我意識到這是不準確一樣您發佈的查詢。最大的區別是,如果一行實際插入tableA(即沒有重複的行錯誤),則上述語句不會在tableB的第一個字段中插入值1。如果這是你真正想要的,那麼下面應該工作:

INSERT IGNORE INTO tableA VALUES (A, B, C); 
SET @id = LAST_INSERT_ID(); 
INSERT INTO tableB SELECT IF(@id IS NOT NULL, 1, id) 
        FROM tableA 
        WHERE a=A AND b=B AND c=C; 

而且我猜想那裏LAST_INSERT_ID()將返回NULL,而不是上次成功插入的實際自動遞增值。我沒有證實這種實際行爲。