2012-07-18 29 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