【问题标题】:SQL Statement fails, even if there are entities in the dbSQL 语句失败,即使 db 中有实体
【发布时间】:2012-09-18 08:03:05
【问题描述】:

我有一个叫做 Produkt 的表,在这个表中有几个叫做 test 的产品。

当我想做那个代码时:

public Produkt findByName(String name) throws SQLException{
    log.error("Enter findByName with parameters: " + name);
    PreparedStatement ps;
    ResultSet rs = null;
    String query = "SELECT * FROM Produkt WHERE name=" + name;
    ps=hsqlmanager.getConnection().prepareStatement(query);
    rs = ps.executeQuery();
    ps.close();
    if(rs.next()) return(new Produkt(rs));
    else return(null);
}

它总是给我一个 sql 错误:

Exception in thread "main" java.sql.SQLSyntaxErrorException: user
lacks privilege or object not found: TEST   at
org.hsqldb.jdbc.Util.sqlException(Unknown Source)   at
org.hsqldb.jdbc.Util.sqlException(Unknown Source)   at
org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)    at
org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)     at
dao.DAOProdukt.findByName(DAOProdukt.java:157)  at
dao.test_produkt_dao.main(test_produkt_dao.java:23)

为什么?我很欣赏你的回答!!!

更新:

为什么 PS 使用不当?请告诉我,以便我可以从中学习?

【问题讨论】:

    标签: java sql eclipse hsqldb


    【解决方案1】:

    您根本不应该在 SQL 中包含该值。这样做会招致 SQL 注入攻击,除非您非常小心引用。 (对于非字符串值,它也引入了潜在的不正确字符串转换。哦,它有效地将代码与数据混合在一起。只需对 SQL 中的变量值说“不”...)

    改为使用PreparedStatement 和参数,然后将参数的值设置为您要查找的名称。例如:

    String query = "SELECT * FROM Produkt WHERE name = ?";
    PreparedStatement ps = hsqlmanager.getConnection().prepareStatement(query);
    ps.setString(1, name);
    ResultSet rs = ps.executeQuery();
    

    请注意,您还应该在 finally 块中包含 close() 语句,以避免在引发异常时泄漏资源。

    有关 HSQLDB 特定的详细信息,请参阅 HSQLDB 用户指南的 Data Access and Change 部分,或参阅 JDBC tutorial on prepared statements 了解更多通用信息。

    【讨论】:

    • 我怎样才能将名字输入到查询中?请解释那部分!
    【解决方案2】:

    您应该正确使用 PreparedStatements 来防止 SQL 注入。它还会在参数周围写上引号,这是必要的。

    String query = "SELECT * FROM Produkt WHERE name=?";
    PreparedStatement ps=hsqlmanager.getConnection().prepareStatement(query);
    ps.setString(1, name);
    

    【讨论】:

    • 我的版本怎么会导致sql注入?
    • @maximus:您当前的版本根本无法使用,因为没有引用 - 但请参阅bobbytables.com 了解有关 SQL 注入及其发生方式的更多信息。 (或者做一些一般性的研究——仅仅搜索 sql 注入攻击会让你得到很多解释问题的结果。)
    【解决方案3】:

    您正在生成一个无效的 SQL 语句,您的 name 参数周围没有引号

    String query = "SELECT * FROM Produkt WHERE name='" + name + "'";
                                                     ^--      ^^^^^^
    

    【讨论】:

    • 看起来 OP 错误地使用了 Prepared Statements。
    • 这个真的应该换成"SELECT * FROM Produkt WHERE name=?" and a call to setString()`。
    • 为什么我的准备好的语句被错误地使用了?请告诉我,以便我学习!
    • 这只是在邀请 SQL 注入攻击。准备好的报表 FTW。
    猜你喜欢
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2017-06-14
    • 2017-10-27
    相关资源
    最近更新 更多