MySQLSyntaxErrorException靠近“?”在尝试执行PreparedStatement时

时间:2010-11-09 06:36:45

标签: java mysql jdbc

我正在尝试使用Java中的PreparedStatement执行查询。

当我尝试执行查询时出现错误号1064(语法错误)。

我已在MySQL查询浏览器中使用替换值对此进行了测试,其工作正常。

我的代码出了什么问题?

以下是相关代码:

String query = "select MemberID, MemberName from members where MemberID = ? or MemberName = ?";
Connection conn = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, 2);
s.setString(2, "zen");
ResultSet rs = s.executeQuery(query);

以下是我得到的例外情况:

  

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:你有一个   SQL语法错误;查看与您的手册相对应的手册   MySQL服务器版本正确的语法使用附近'?或会员名称   =?'在第1行

2 个答案:

答案 0 :(得分:4)

  

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:   您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以便在'附近使用正确的语法?或MemberName =?'在第1行

MySQL不理解SQL查询中?的含义。这确实是无效的SQL语法。所以它不会被PreparedStatement取代。猜猜怎么着?

PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, intValue);
s.setString(2, strValue);        
rs = s.executeQuery(query); // Fail!

您正在使用原始查询覆盖准备好的查询!您需要调用无争论的PreparedStatement#executeQuery()方法而不是Statement#executeQuery(String)

PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, intValue);
s.setString(2, strValue);        
rs = s.executeQuery(); // OK!

与此问题无关,您的代码正在泄漏资源。数小时后,数据库将耗尽,您的应用程序将崩溃。要解决此问题,您需要遵循在Connection块的Statement块中关闭ResultSetfinallytry的JDBC惯用语。被收购了。查看JDBC basic tutorial了解更多详情。

答案 1 :(得分:0)

如果您查看Statement的{​​{3}}(PreparedStatement的超类),则executeQuery(String)executeUpdate(String)的方法docs会这样说:

  

注意:不能在PreparedStatementCallableStatement上调用此方法。

这就是您在这里所做的:在executeQuery(String)对象上从Statement调用PreparedStatement

现在,由于javadocs说您“无法”执行此操作,因此您获得的实际行为是不确定的……并且可能取决于JDBC驱动程序。在这种情况下,您正在使用的MySQL驱动程序似乎将此解释为意味着您将更新作为非准备好的语句进行,因此?标记不会被解释为参数占位符。这导致服务器端SQL解析器说“语法错误”。

(如果这样做,对于程序员,如果MySQL驱动程序引发了另一个未经检查的异常,这会更容易;例如UnsupportedOperationException。但是,标准JDBC javadocs并未说明在这种情况下会发生什么情况。由供应商决定其驱动程序将执行什么操作。)