PreparedStatement不返回有序的ResultSet

时间:2009-12-09 16:26:49

标签: java jdbc prepared-statement

我遇到了一些问题,我确信这是愚蠢的。

所以我有一个像

这样的查询
SELECT name, id, xyz FROM table ORDER BY ?

然后在路上设置了?做一个

ps.setString(1, "xyz");

我在控制台中输出查询和xyz的值。当我遍历从PreparedStatement返回的ResultSet时,值的顺序不正确。它们处于返回的顺序,就像我已经关闭了ORDER BY子句一样。当我将查询和值复制/粘贴到TOAD时,它会运行并正确返回。

为什么ResultSet没有以正确的顺序返回的任何想法?

5 个答案:

答案 0 :(得分:13)

数据库会将查询视为

SELECT name, id, xyz FROM table ORDER BY 'xyz'

也就是说,通过常量表达式排序(在这种情况下为字符串'xyz')。任何订单都会满足。

答案 1 :(得分:5)

?对于参数,您不能使用它来插入列名。生成的语句看起来像

SELECT name, id, xyz FROM table ORDER BY 'xyz'

以便您的条目按字符串'xyz'排序,而不是按列xyz的内容排序。

答案 2 :(得分:3)

为什么不跑:

ps.setInteger(1, 3);

问候。

编辑:AFAIK Oracle 10g支持它。

答案 3 :(得分:0)

PreparedStatement占位符不适用于表名和列名。它们仅用于实际列值。

然而,您可以使用String#format(),这也是我经常这样做的方式。例如:

private static final String SQL_SELECT_ORDER = "SELECT name, id, xyz FROM table ORDER BY %s";

...

public List<Data> list(boolean ascending) {
    String order = ascending ? "ASC" : "DESC";
    String sql = String.format(SQL_SELECT_ORDER, order);
    ...

另一个例子:

private static final String SQL_SELECT_IN = "SELECT name, id, xyz FROM table WHERE id IN (%s)";

...

public List<Data> list(Set<Long> ids) {
    String placeHolders = generatePlaceHolders(ids.size()); // Should return "?,?,?..."
    String sql = String.format(SQL_SELECT_IN, placeHolders);
    ...
    DAOUtil.setValues(preparedStatement, ids.toArray());
    ...

答案 4 :(得分:0)

数据库将看到这样的查询

SELECT name, id, xyz FROM table ORDER BY 'xyz'

我认为你应该添加更多变量,如order_field和order_direction

我假设你有一个像下面这样的方法,我给你一个解决它的例子

pulbic List<Object> getAllTableWithOrder(String order_field, String order_direction) {
    String sql = "select * from table order by ? ?";
    //add connection here

    PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql);
    ps.setString(1,order_field);
    ps.setString(2,order_direction);

    logger.info(String.valueOf(ps)); //returns something like: com.mysql.jdbc.JDBC4PreparedStatement@a0ff86: select * from table order by 'id' 'desc'

    String sqlb = String.valueOf(ps);
    String sqlc = sqlb.replace("'"+order_field+"'", order_field);
    String sqld = sqlc.replace("'"+order_direction+"'", order_direction);

    String[] normQuery = sqld.split(":");

    ResultSet result = conn.createStatement().executeQuery(normQuery[1]);

    while(result.next()) { 
        //iteration
    }

}