【问题标题】:PreparedStatement not returning ordered ResultSetPreparedStatement 未返回有序的 ResultSet
【发布时间】:2009-12-09 16:26:48
【问题描述】:

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

所以我有一个类似的查询

SELECT name, id, xyz FROM table ORDER BY ?

然后在路上设置?做一个

ps.setString(1, "xyz");

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

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

【问题讨论】:

    标签: java jdbc prepared-statement


    【解决方案1】:

    数据库会将查询视为

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

    也就是说,按常量表达式排序(在本例中为字符串'xyz')。任何订单都会满足这一点。

    【讨论】:

    • jeebus,你认为我会想到这一点。但这清除了它。谢谢!
    • 您只能在准备好的语句中指定常量。
    【解决方案2】:

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

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

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

    【讨论】:

    • 现在我看到它是如此明显,但我花了很多时间试图找出为什么我的结果没有排序。这总结得很好。
    【解决方案3】:

    为什么不跑:

    ps.setInteger(1, 3);
    

    问候。

    编辑:AFAIK Oracle 10g 支持它。

    【讨论】:

      【解决方案4】:

      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());
          ...
      

      【讨论】:

      • 不应该是"SELECT name, id, xyz FROM table ORDER BY %s %s",然后是String.format(SQL_SELECT_ORDER, orderby, order);
      【解决方案5】:

      数据库会看到这样的查询

      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
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多