【问题标题】:CursorIndexOutOfBounds Exception: Index 0 requested, with a size of 0CursorIndexOutOfBounds 异常:请求索引 0,大小为 0
【发布时间】:2022-03-17 21:31:00
【问题描述】:

我尝试读取 SQLite 数据库列并将每个值存储在字符串数组中。我做了以下但它返回异常cursoroutofbounds。帮我弄清楚我做错了什么?

 public String[] getPlaces(){
   SQLiteDatabase db = this.getReadableDatabase();

    String [] columns = {"place1"};
    c = db.query("rates_table", columns, null, null, null, null, null);
    String[] places = new String[c.getColumnCount()];
    c.moveToNext();

    for(int i=0; i<c.getColumnCount(); i++)
        places[i] = c.getString(i);

    return places;
}

【问题讨论】:

  • 这在很多层面上看起来都是错误的。检查您的查询。您的 where 子句只是“place1”,根本没有任何意义。您的循环没有意义,因为它也没有移动光标位置

标签: android android-sqlite android-cursor


【解决方案1】:

这里:

String[] places = new String[c.getColumnCount()];

c.getColumnCount() 将返回行中列的count 而不是number of rows in column。使用c.getCount()初始化places数组:

String[] places = new String[c.getCount()];

或者使用ArrayList

【讨论】:

    【解决方案2】:

    我研究了一段时间,找到了解决方案:

     public String[] getPlaces(){
            SQLiteDatabase db = this.getReadableDatabase();
    
            String [] columns = {"place1"};
            c = db.query("rates_table", columns, null, null, null, null, null);
    
            c.moveToFirst();
            ArrayList<String> places = new ArrayList<String>();
            while(!c.isAfterLast()) {
                places.add(c.getString(c.getColumnIndex("place1")));
                c.moveToNext();
            }
            c.close();
            return places.toArray(new String[places.size()]);
    
        }
    

    【讨论】:

      【解决方案3】:

      您需要在多个地方更改查询和进一步处理。将查询方法的第三个参数更正为适当的 where 子句或将其保留为空。正确循环光标并将其添加到您的字符串中。

      public String[] getPlaces(){
          SQLiteDatabase db = this.getReadableDatabase();
      
          String [] columns = {"place1"};
          c = db.query("rates_table", columns, null, null, null, null, null);
      
      
          if (c.getCount() > 0) {   
             String[] places = new String[c.getCount()];
             int i=0;
             c.moveToFirst();
             do {
               places[i] = c.getString(c.getColumnIndex(0))); 
             } while (c.moveToNext());
             return places;
          }
          c.close();
          db.close();
      
      
      }
      

      【讨论】:

      • 一切都好,但我认为 String[] 和 return 语句应该在循环之外。
      • 它们都在循环之外。他们就在里面。 String[] 您不能在 if 之外声明,直到您确定计数 >0 否则您可以使用可用于动态值数量的 arraylist。返回在 if 内部,因为您的 String[] 无法在 if 外部访问。现在这将给出一个警告,即您的方法并不总是有一个返回值,您可以在外部返回 null,因为在这种情况下,您将找不到任何值,并且您可以处理调用该方法的位置。
      • 你还需要添加一个 try catch 并在 finally 中执行 close 语句。我向您提示了数据库查询工作所需的内容。 :)
      • 你的想法不错。我刚刚找到了答案。希望你能看到我的回答。
      • 是的 看到了答案。您需要将 1 标记为答案,这样人们就不会继续添加到此查询中。同样在您的回答中,您忘记关闭数据库,当您稍后再次执行查询时会出错。
      【解决方案4】:

      首先你对c = db.query("rates_table", columns, "place1", null, null, null, null);有疑问

      第三个参数将导致没有行被选中。

      您可以使用 c = db.query("rates_table", columns, null, null, null, null, null); ,它将返回所有行。

      或者您可以使用c = db.query("rates_table", columns, "place1 = 'myplace'", null, null, null, null);,在这种情况下,只会显示在place1 列中具有myplace 值的行。

      最佳实践方法是在第三个参数中使用 ? 占位符(例如“place1=?”)和第四个参数中的相应参数(例如new String[]{"myplace"}),因此要复制上一个查询,您可以使用c = db.query("rates_table", columns, "place1=?", new String[]{"myplace}, null, null, null);

      使用c.moveToNext,将尝试移动到光标的下一行(最初是第一行)。但是,如果它不能移动(即没有行,就像上面描述的那样),它不会失败,而是返回 false(如果光标可以移动,则返回 true)。

      所以你需要检查这个,否则在没有行的情况下,尝试访问行将失败,游标越界请求索引 0,大小为 0(即你请求第一个(索引 0)当游标大小(行数)为0时。

      有多种检查方法。

      但是我怀疑你会想知道为什么你的循环只显示 1 列。那是因为您在查询中说过只获取 1 列。

      如果您将查询的第二个参数更改为 null,它将获取所有列。

      您想返回一个包含所有地点的数组。

      那么假设:-

      // get Cursor with all rows(3rd parm null) for the place1 column (2nd parm)
      c = db.query("rates_table", columns, null, null, null, null, null);
      
      // Create String array according to the number of rows returned.
      String[] places = new String[c.getCount()];
      
      // loop through all rows setting the respective places element with the 
      // value obtained from the Cursor
      while (c.moveToNext) {
          places[c.getPosition()] = csr.getString(csr.getColumnIndex("place1")); 
      }
      
      csr.close(); // Should always close a Cursor
      return places;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-02
        • 2016-02-09
        • 2012-05-01
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        相关资源
        最近更新 更多