我编写了以下代码。但我收到 MySQL 异常,要求在“?”附近使用正确的语法。 你能帮我解决这个问题吗?
public static void inbox(String username) {
String query_recipient = "SELECT user_id, first_name, last_name FROM user_info WHERE username = '" + username + "' ";
String query = "SELECT sub, msg FROM message WHERE recipient = ?";
Statement s = null;
PreparedStatement ps = null;
ResultSet rs = null;
ResultSet rs1 = null;
int userId = 0;
try {
s = Connect.con.createStatement();
rs = s.executeQuery(query_recipient);
rs.next();
userId = rs.getInt("user_id");
ps = Connect.con.prepareStatement(query);
ps.setInt(1, userId);
rs1 = ps.executeQuery(query);
while (rs1.next()) {
System.out.println(rs1.getString("sub"));
System.out.println(rs1.getString("msg"));
}
} catch (SQLException ex) {
Logger.getLogger(UserBAL.class.getName()).log(Level.SEVERE, null, ex);
} //end catch
} //end inbox()
编辑:这是错误消息
SEVERE: null
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '?' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1053)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2788)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2738)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1617)
at msg_pkg.MsgBAL.inbox(MsgBAL.java:82)
at msg_pkg.MsgBAL.main(MsgBAL.java:116)
最佳答案
我在您的代码中发现了一些错误:
- 您正在将 SQL 语句传递给准备好的语句...这不仅没有必要,而且是错误的。检查the documentation for the
executeQuery()
method of prepared statements. - 检索用户结果集后,只需移至下一行...这可能有效,但正确的方法是:转到结果集的第一行(使用
rs.first()
)。同样的事情发生在下面的几行中:您移动到消息结果集的下一行;您应该首先移动到第一行之前,然后移动到下一行(当有下一行时)。
- (个人建议)第一个查询容易受到SQL injection attacks的影响。既然您已经在使用准备好的语句,为什么不使用准备好的语句来获取用户 ID?
- (个人建议),我认为最好使用
try
with resources ,而不是使用try ... catch
风格(这并没有错)。风格。这样,您就可以在程序完成资源(在本例中为准备好的语句)后强制关闭它们。
让我们稍微清理一下您的代码:
public static void inbox(String username) {
/*
First: Avoid SQL injection risks: use a prepared statement
to get user data.
*/
String qryRec = "SELECT user_id, first_name, last_name "
+ "FROM user_info "
+ "WHERE username = ?";
String qryMsg = "SELECT sub, msg "
+ "FROM message "
+ "WHERE recipient = ?";
ResultSet rsRec = null,
rsMsg = null;
// "try-with-resources"
try(
PreparedStatement psRec = Connect.con.prepareStatement(qryRec);
PreparedStatement psMsg = Connect.con.prepareStatement(qryMsg);
) {
// Set the parameter for psRecipient, and execute the query
psRec.setString(1, username);
rsRec = psRec.executeQuery(); // No need to pass the query
// as an argument here; it's
// already prepared
// Go to the first row of rsRecipient
rsRec.first();
// Set the parameter for psMessage, and execute the query
psMsg.setInt(1, rsRecipient.getInt("user_id");
rsMsg = psMmsg.executeQuery(); // No need to pass the query
// as an argument here; it's
// already prepared
// Go to the resultset "header" (i.e. before the first row
rsMsg.beforeFirst();
while(rsMsg.next()) {
System.out.println(rsMsg.getString("sub"));
System.out.println(rsMsg.getString("msg"));
}
// Remember to close the result sets
try {
if(rsRec != null)
rsRec.close();
} catch(SQLException e) {/*Ignore*/} finally {rsRec = null;}
try {
if(rsMsg != null)
rsMsg.close();
} catch(SQLException e) {/*Ignore*/} finally {rsMsg = null;}
} catch(SQLException e) {
// Handle exception
}
}
希望这有帮助
关于预准备语句中的 MYSQL 异常在 '?' 附近使用正确的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30038718/