我有这个方法来加载对象,但是当我运行sql代码时,它给了我一个语法错误。
public void loadObjects() {
Statement s = setConnection();
// Add Administrators
try {
ResultSet r = s.executeQuery("SELECT * FROM Administrator;");
while (r.next()) {
Administrator getUser = new Administrator();
getUser.ID = r.getString(2);
ResultSet r2 = s.executeQuery("SELECT * FROM Userx WHERE ID= {" + getUser.ID + "};");
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
我已尝试插入其他问题中所述的花括号,但我要么做错了要么行不通。 此方法应该能够加载所有管理员,但我相信它只插入一半的ID。 它获得的ID由数字和字符组成;例如“26315G”
错误 - com.microsoft.sqlserver.jdbc.SQLServerException:'26315'附近的语法不正确。
编辑 -
private java.sql.Connection setConnection(){
java.sql.Connection con = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url = "jdbc:sqlserver://" + host + ";DatabaseName=" + database + ";integratedSecurity=true;";
con = DriverManager.getConnection(url, username, password);
} catch(Exception e) {
System.out.println(e);
}
return con;
}
public void loadObjects() {
java.sql.Connection con = setConnection();
// Add Administrators
try {
PreparedStatement sql = con.prepareStatement("SELECT * FROM Administrator");
ResultSet rs = sql.executeQuery();
while (rs.next()) {
Administrator getUser = new Administrator();
getUser.ID = rs.getString(2);
PreparedStatement sql2 = con.prepareStatement("SELECT * FROM Userx WHERE ID=?");
sql2.setString(1, getUser.ID);
ResultSet r2 = sql2.executeQuery();
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
答案 0 :(得分:5)
实际上,这不是在JDBC中执行此操作的方法。这样,即使您对语法错误进行排序,您的代码也容易受到SQL注入攻击。
正确的方法是:
// Let's say your user id is an integer
PreparedStatement stmt = connection.prepareStatement("select * from userx where id=?");
stmt.setInt(1, getUser.ID);
ResultSet rs = stmt.executeQuery();
通过这种方式,您可以防止在应用程序请求参数中注入SQL的任何尝试
答案 1 :(得分:1)
首先:如果你同时使用结果集,必须为每一个使用单独的语句(你不能在两个r和r2之间共享Statement)。而且,在阅读之前你缺乏r2.next()。
另一方面:在循环中使用PreparedStatement可以更有效地重写查询。
所以我会选择这样的事情:
public void loadObjects() {
try (
Statement st = getConnection().createStatement();
//- As you read (later) only id, then why to use '*' in this query? It only takes up resources.
ResultSet rs = st.executeQuery("SELECT id FROM Administrator");
PreparedStatement ps = getConnection().prepareStatement("SELECT * FROM Userx WHERE ID = ?");
ResultSet r2 = null;
) {
while (rs.next()) {
Administrator user = new Administrator();
user.ID = rs.getString("id");
ps.setInt(1, user.ID);
r2 = ps.executeQuery();
if (r2.next()) {
user.name = r2.getString(2);
user.surname = r2.getString(3);
user.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(user);
}
else {
System.out.println("User with ID=" + user.ID + " was not found.");
}
}
}
catch (Exception x) {
x.printStacktrace();
}
}
请注意使用Java7自动关闭功能(您没有关闭代码中的资源)。最后一点:在你没有在查询中分离语句之前,对于JDBC文档,你不应该放置';'在语句结束时(在所有情况下,您不应将';'作为查询字符串中的最后一个字符)。
答案 2 :(得分:0)
您不应该使用{},并且不应该将参数附加到这样的SQL查询中。
删除花括号并改为使用PreparedStatement。