Sqlite + java,用预处理语句做的怪异行为

时间:2017-01-01 19:51:18

标签: java sqlite

我遇到了一个我无法解释的问题,使用java / sqlite:

    String sql = "Select date, type FROM line ORDER BY ?";
    PreparedStatement st = DB.getConnexion().prepareStatement(sql);
    st.setString(1, sort);
    ResultSet rs = st.executeQuery();

这段代码给了我错误的顺序(默认顺序)[并相信我检查并重新检查参数是否正常]

    String sql = "Select date, type FROM line ORDER BY " + sort;
    PreparedStatement st = DB.getConnexion().prepareStatement(sql);
    //st.setString(1, sort);
    ResultSet rs = st.executeQuery();

这个产生了预期的结果。我在这里有点茫然,这对我来说毫无意义。 我试图重新启动eeclipse,重建项目,直接从sqlite浏览器测试我的请求,检查参数和结果在每个可能的地方,但似乎sqlite的setString()函数没有正确地属性我的参数,它甚至没有崩溃或产生错误。

我要么错过了一些非常愚蠢的东西,要么就会发生一些非常错误的事情。

2 个答案:

答案 0 :(得分:3)

SQL语言接受此语法实际上令人惊讶。它可能在其他一些方面失败。

无论如何,sort被解释为字符串常量,因此排序算法的所有行都具有相同的值。因此,由于它们具有相同的值,因此它保持原始顺序。

你不能使用这样的动态语句,唯一的方法是将排序直接附加到语句字符串的第二种解决方案。

答案 1 :(得分:1)

那是因为您告诉SQL该参数是一个字符串。让我们说参数是Name。你的陈述将是这样的:

Select date, type FROM line ORDER BY 'Name'

这在技术上可能是有效的SQL,但它不会对列有用地排序 - 它不是按名称列排序,它按字面顺序排序'名称&# 39;,它始终是相同的常量字符串。

我认为你不能使用参数。您必须更改语句本身才能拥有所需的排序列。当然,您希望确保在执行此操作时不允许注入漏洞,因此您可能不希望将变量中的任何内容粘贴到语句中。您可能希望拥有一个包含表格中可能列的白名单,并拒绝任何不属于这些列的内容。