2017-07-27 79 views
0

我尝试读取SQLite数据库列并将每个值存储在一个字符串数组中。我做了以下,但它返回异常cursoroutofbounds。帮我弄清楚我做错了什么?CursorIndexOutOfBounds异常:请求索引0,大小为0

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; 

    } 
+2

这看起来错在一大堆的水平。检查你的查询。你的where子句只是“place1”,根本没有任何意义。你的循环没有意义,因为它没有移动光标位置以及 –

+0

谢谢,但我只是找到了我正在寻找的答案。看到我的答案。 –

回答

1

这里:

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

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

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

或者使用ArrayList

0

您需要更改查询并在多个地方进一步处理。将您的查询方法的第三个参数修正为适当的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(); 


} 
+0

所有不错,但我认为String []和return语句应该在循环之外。 –

+0

他们都在循环之外。他们只是在里面。 String []你不能在外面声明if直到你确定你的count> 0,否则你可以使用arraylist,它可以用于动态数值。如果因为你的String []不能在外面访问,返回是在里面。现在,这会给出一个警告,即您的方法并不总是有返回值,您可以在外部返回null,因为在这种情况下,您将找不到任何值,并且您可以处理调用该方法的位置。 –

+1

您还需要添加try catch,并在finally中执行close语句。我向你提供了DB查询工作所需的一些提示。 :) –

1

我摸索出了一段时间,发现了解决办法:

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

    } 
0

首先,你有一个问题与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值的行。

最佳实践方法是将第3个和第4个参数结合使用占位符在第三PARM(如“PLACE1 =?”),并在第4个参数对应的ARGS(例如,新的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; 
相关问题