Java JDBC不正确的语法错误

时间:2014-02-06 13:37:50

标签: java jdbc

我有这个方法来加载对象,但是当我运行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);
    }

}

3 个答案:

答案 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。

请参阅http://www.unixwiz.net/techtips/sql-injection.html