2012-07-18 28 views
0

我目前計算值,以填補15個長槍記錄的數據庫。第7工廠去只是鰭片,電子但是現在我的更新查詢開始給人的問題: 現在&然後隨機字母變成一些jibberish。 在java中我生成查詢這樣做的:MySQL查詢變異上巨大的情況下:

String updateSql = "UPDATE VanNaar SET time = CASE ID "; 
     for (int i = 0; i < routes.size(); i++) { 
      updateSql += " WHEN " + routes.get(i).ID + " THEN " + routes.get(i).driveTime; 
     } 
     updateSql += " END, "; 
     updateSql += " distance = CASE ID "; 
     for (int i = 0; i < routes.size(); i++) { 
      updateSql += " WHEN " + routes.get(i).ID + " THEN " + routes.get(i).distance; 
     } 
     updateSql += " END WHERE id IN ("; 
     for (int i = 0; i < routes.size(); i++) { 
      updateSql += routes.get(i).ID + ","; 
     } 
     updateSql = updateSql.substring(0, updateSql.length() - 1); 
     updateSql += ");"; 

如前面提到的這工作得很好。這裏是我什麼的Java trows現在:

...MySQL server version for the right syntax to use near '×HEN 8284022 THEN 999.999 WHEN 8284023 THEN 3791.0 WHEN 8284024 THEN 378... 

或者

...MySQL server version for the right syntax to use near 'WÈEN 7468574 THEN 2273.0 WHEN 7468575 THEN 2410.0 WHEN 7468576 THEN 2472.0 W' at line 1 

通知的weirdisch a^A-,最終exmpale,提醒你大膽tekst:

...MySQL server version for the right syntax to use near **'Â** WHEN 7228125 THEN 48590.0 WHEN 7228126 THEN 47910.0 WHEN 7228127 THEN...

...

更新: 似乎有愈演愈烈之勢..:

Unknown column '9°22331' in 'where clause' 
+0

與'routes.get(i).ID'和'routes.get(i).distance'有關的類型是什麼? – 2012-07-18 17:53:25

回答

2

我不是Java專家,但你不應該使用在首位StringBuilder?可能甚至使用prepared statement?你可以在球泡預處理語句與一個StringBuilder但不是

updateSql += " WHEN " + routes.get(i).ID + " THEN " + routes.get(i).driveTime; 

無處不在,你會做這樣的事情

myStrngBldr.append(" WHEN ? THEN ?"); 

myStrngBldr.append(" WHEN @foo1 THEN @foo2"); 

如果命名參數的支持(不知道了),後來添加的實際參數:

myPrepdStmt = myConn.prepareStatement(myStrngBldr.toString()); 

myPrepdStmt.setInt(1, routes.get(i).ID); 
myPrepdStmt.setFloat(2, routes.get(i).driveTime); 
... 
myPrepdStmt.executeUpdate(); 

This page應該可以幫到你。

什麼是真正導致「怪畸形字符串」:我不知道。我最好的猜測是你必須在所有這些ID和其他非字符串值上使用類似.ToString()的東西,因爲你要連接一個字符串。也許,不知何故,這些值被解釋爲charcodes(因爲它們沒有明確鑄造爲字符串),從而導致奇怪的字符。

另一種猜測是:你實際上是在建設,存儲器15萬個查詢它們發送到數據庫之前?還是每個查詢都單獨發送到數據庫?也許你試圖在內存中存儲一​​個巨大的字符串的事實會導致一些問題(儘管它不應該導致你在這裏描述的問題)。

+0

我每批處理(5000個請求,所以後面的評論是不適用的)。 – FireFox 2012-07-18 18:02:53

+0

你的方法似乎工作。謝謝。扼殺它似乎表現更好。 – FireFox 2012-07-18 18:28:37

1

您可能需要考慮用兩個CASE選擇器和一個IN以及每個行的單個UPDATE語句替換巨大的更新。我知道問題不是由此造成的,但它可能是更清潔和更有效的解決方案。如果您的數據庫連接器支持每個執行多條語句,你可以這樣做以下:

int batchSize = 0; 
StringBuilder sb = new StringBuilder(); 
for (Route r: routes) { 
    sb.append("UPDATE VanNaar SET") 
     .append(" time = '").append(r.driveTime).append("',") 
     .append(" distance = '").append(r.distance).append("'") 
     .append(" WHERE ID = '").append(r.ID).append("'; "); 
    if (++batchSize == BATCH_SIZE) { 
     connector.exec(sb.toString()); 
     sb = new StringBuilder(); 
     batchSize = 0; 
    } 
} 
if (sb.length() > 0) { 
    connector.exec(sb.toString()); 
} 

這將讓任何改造基礎值類型爲StringStringBuilder照顧。如果driveTimedistanceID已經是字符串,那麼您必須使用適當的JDBC方法正確地轉義它們。

您可能會更好地使用@RobIII建議的準備好的語句來處理此類事件,因爲它們會自動處理SQL注入問題。

+0

寶貴的意見,今天我學到了很多:) – FireFox 2012-07-18 18:29:39