使用PreparedStatement遇到的问题 - Java

3

我正在尝试使用PreparedStatement进行SQLite搜索。语句运行正常,但是使用PreparedStatement时出现了问题。

这是我的搜索方法:

public void searchSQL(){
        try {
            ps = conn.prepareStatement("select * from ?");
            ps.setString(1, "clients");
            rs = ps.executeQuery();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

但是我遇到了以下错误:

java.sql.SQLException: near "?": 语法错误 org.sqlite.DB.throwex(DB.java:288) org.sqlite.NestedDB.prepare(NestedDB.java:115) org.sqlite.DB.prepare(DB.java:114) org.sqlite.PrepStmt.(PrepStmt.java:37) org.sqlite.Conn.prepareStatement(Conn.java:231) org.sqlite.Conn.prepareStatement(Conn.java:224) org.sqlite.Conn.prepareStatement(Conn.java:213)

谢谢


我假设你在实际代码中不会真正使用 select *。如果你正在将结果集映射到一个对象,那么当其他人更改源表时,你的逻辑将立即中断。 - Perception
3个回答

4

列参数可以是表名之外的任何内容; 您的方法必须像这样:

public void searchSQL()
{
    try 
    {
        ps = conn.prepareStatement("select * from clients");
        rs = ps.executeQuery();
    }
    catch (SQLException ex) 
    {
        ex.printStackTrace();
    }
}

如果我像这样做,它就可以正常工作,查看此函数:

public void displayContentOfTable()
{
    java.sql.ResultSet rs = null;
    try
    {
        con = this.getConnection();
        java.sql.PreparedStatement pstatement = con.prepareStatement("Select * from LoginInfo");
        rs = pstatement.executeQuery();

        while (rs.next())
        {
            String email = rs.getString(1);
            String nickName = rs.getString(2);
            String password = rs.getString(3);
            String loginDate = rs.getString(4);
            System.out.println("-----------------------------------");
            System.out.println("Email : " + email);
            System.out.println("NickName : " + nickName);
            System.out.println("Password : " + password);
            System.out.println("Login Date : " + loginDate);
            System.out.println("-----------------------------------");
        }
        rs.close();  // Do remember to always close this, once you done 
                     // using it's values.
    }
    catch(Exception e)  
    {
        e.printStackTrace();
    }       
}

将ResultSet作为局部变量,而不是实例变量(与您的做法相同)。在完成后关闭它,通过键入rs.close()rs = null


@Downvoter:出了什么问题?请解释一下,分享一下您的智慧。 - nIcE cOw
@user1232535:不用谢,保持微笑 :-) - nIcE cOw

3

在准备好的语句中传递表名是不可能的。

当您想要在 where 子句中传递变量时,可以使用 setString 方法,例如:

select * from clients where name = ?

谢谢大家,我现在不再遇到那个错误了。 但是,我现在无法使用PreparedStatement从ResultSet获取结果 :( int xRows = 0; while(con_cli.rs.next()) { int cod = con_cli.rs.getInt(1); String name = con_cli.rs.getString(2); String pet = con_cli.rs.getString(3); System.out.println("Cod: " + cod + " - Name: " + name + " - Pet: " + pet); xRows ++;
} System.out.println(xRows + ": found."); 感谢您的回复。
- Galla

1

谢谢大家的回复,现在它正常工作了。 我注意到 SQL 查询也不能将 ? 保留到列中。 因此,这个 SQL 查询转换为 PreparedStatement 是可以工作的:

String sql = "select * from clients where name like ?";
ps = conn.prepareStatement(sql);
ps.setString(1, "a%");
rs = ps.executeQuery();

但是,如果我尝试将列作为setString使用,它不起作用:

String sql = "select * from clientes where ? like ?";
ps = conn.prepareStatement(sql);
ps.setString(1, "name");
ps.setString(2, "a%"):
rs = ps.executeQuery();

我是正确的吗?还是有什么方法可以绕过这个问题?谢谢。


非常正确,我所说的“columns”指的是列参数,我的错,我没有再次检查它,你的第一段代码是正确的方式,可以传递列参数。 - nIcE cOw
谢谢回复,Bali。那么,PreparedStatment就不能完成我需要的工作了 :´( - Galla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接