SimpleCursorAdapter很难使用

时间:2011-07-04 16:10:26

标签: android sqlite listview simplecursoradapter

我长期以来一直被困在一个地方,即使用

 SimpleCursorAdapter 

因为它在返回正确值时失败。我在SO本身看过类似的很多帖子,说我应该在游标数据库查询中添加_id列,而不是我应该做的

 db.rawQuery(String,String)

onCreate(..)中的代码是

HospitalData = new Database(this);
HospitalData.open();
Cursor c = HospitalData.getAllRows_Patient_Db();
startManagingCursor(c);
c.moveToFirst();

//HERE SOME LOOP IS NEEDED FOR TRAVERSING AND PUTTING IN THE LISTVIEW
while(c.isAfterLast() == false)
{
    String[] columns = new String[] { c.getString(1), c.getString(2) };
    int[] to = new int[] { R.id.room_number_db, R.id.pt_initial_db };
    adapter = new SimpleCursorAdapter(this,R.layout.patient_db, c,columns,to);
    c.moveToNext();
}
setListAdapter(adapter);

以前我的数据库访问代码如下

 public Cursor getAllRows_Patient_Db() 
{               
    return db.query(DATABASE_PATIENT_TABLE, new String[] {KEY_ROWID, KEY_ROOM_NUMBER,                             
                                                        KEY_PATIENT_INITIAL
            }, 
            null, 
            null, 
            null, 
            null, 
            null);
}

其中KEY_ROWID定义如下

public static final String KEY_ROWID = "_id";

这个错误是

07-04 22:10:23.301: ERROR/AndroidRuntime(16795): Caused by: java.lang.IllegalArgumentException: column '90' does not exist
07-04 22:10:23.301: ERROR/AndroidRuntime(16795):     at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
07-04 22:10:23.301: ERROR/AndroidRuntime(16795):     at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:312)

这里第90列不是列id,但是根据我的数据库是存储在cursor.getString(1)中的数据,但我想这里它试图搜索cursor.getString(0)这是行id。

后来我改变了我的代码如下

public Cursor getAllRows_Patient_Db() 
{
  String db_sel = "SELECT id as _id, KEY_ROOM_NUMBER" +
    ",KEY_PATIENT_INITIAL FROM DATABASE_PATIENT_TABLE";

    return db.rawQuery(db_sel,null);
}

但我仍然得到错误,这次错误是不同的

07-04 21:36:12.510: ERROR/global(9861): Deprecated Thread methods are not supported.

 07-04 21:36:12.950: ERROR/AndroidRuntime(9861): FATAL EXCEPTION: main
 07-04 21:36:12.950: ERROR/AndroidRuntime(9861): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pro/com.pro.CopyOfFirstScreen}: android.database.sqlite.SQLiteException: no such table: DATABASE_PATIENT_TABLE: , while compiling: SELECT id as _id, KEY_ROOM_NUMBER,KEY_PATIENT_INITIAL FROM DATABASE_PATIENT_TABLE

 07-04 21:36:12.950: ERROR/AndroidRuntime(9861): Caused by: android.database.sqlite.SQLiteException: no such table: DATABASE_PATIENT_TABLE: , while compiling: SELECT id as _id, KEY_ROOM_NUMBER,KEY_PATIENT_INITIAL FROM DATABASE_PATIENT_TABLE

我很久以前就被困住了,请帮助!!

编辑:好的,现在和你们一起帮助我的查询语句是正确的,谢谢你,对不起,我不善于理解数据库查询的语法,但我正在努力学习

更改后的工作查询

String db_sel = "SELECT _id as _id, room_number" +",patient_initial FROM " + DATABASE_PATIENT_TABLE;

实际上我不得不用键值

更改声明的String
public static final String KEY_ROWID = "_id";
public static final String KEY_ROOM_NUMBER = "room_number";
public static final String KEY_PATIENT_INITIAL = "patient_initial";

但是现在我看到另一个问题不是来自查询语句,而是我访问或使用simplecursorAdapter的方式

DB Table

正如您所看到我的表有2行3列,现在我想从第2列和第3列中获取数据并将其放入listview中。 但在查询修复后,我收到了另一个错误

原来是

   String[] columns = new String[] {c.getString(1), c.getString(2) };
        int[] to = new int[] {  R.id.room_number_db, R.id.pt_initial_db };
     adapter = new SimpleCursorAdapter(this,R.layout.patient_db, c,columns,to);
     c.moveToNext();
    setListAdapter(adapter);

错误是

  07-05 21:32:29.228: ERROR/AndroidRuntime(1505): Caused by: java.lang.IllegalArgumentException: column '90' does not exist
  07-05 21:32:29.228: ERROR/AndroidRuntime(1505):     at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
  07-05 21:32:29.228: ERROR/AndroidRuntime(1505):     at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:312)

android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:312)

正如您所看到的那样,尽管正在访问该行,但它正试图访问第一列的数据

之后我在代码中进行了更改

     int x = 0;         
     String[] columns = new String[] { c.getString(0),c.getString(1), c.getString(2) };
        int[] to = new int[] { x, R.id.room_number_db, R.id.pt_initial_db };
     adapter = new SimpleCursorAdapter(this,R.layout.patient_db, c,columns,to);
     c.moveToNext();
    setListAdapter(adapter); 

这只是一个猜测,以便找出SimpleCursorAdapter与普通光标相比有多么不同,我得到的错误是

 07-05 21:34:47.947: ERROR/AndroidRuntime(1966): Caused by: java.lang.IllegalArgumentException: column '1' does not exist
 07-05 21:34:47.947: ERROR/AndroidRuntime(1966):     at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)

我知道这个问题变得太长了:-(你建议我从这里删除一些代码。

3 个答案:

答案 0 :(得分:2)

您是否已阅读错误堆栈的这一部分:

android.database.sqlite.SQLiteException: no such table: DATABASE_PATIENT_TABLE:

? 你在数据库中没有这样的表。这不是CursorAdapter问题。 你的循环似乎完全没有意义 - 只需阅读一些java手册。 好的,让我们开始列出代码中的一些问题:

String[] columns = new String[] { c.getString(1), c.getString(2) };

columns[]应包含名称列而非值... 在while{}循环中,您创建了几十(?)个SimpleCursorAdapters,而只传递了最后一个。 这部分代码:

String db_sel = "SELECT id as _id, KEY_ROOM_NUMBER" +
    ",KEY_PATIENT_INITIAL FROM DATABASE_PATIENT_TABLE";

显然是错的。我假设你有像

这样的东西
private static String DATABASE_PATIENT_TABLE = "patient";

所以只需使用这些常量:

String db_sel = "select id as _id, +"KEY_ROOM_NUMBER+", "+ KEY_PATIENT_INITIAL +" from "+DATABASE_PATIENT_TABLE;

替换:

 String[] columns = new String[] { c.getString(0),c.getString(1), c.getString(2) };
    int[] to = new int[] { x, R.id.room_number_db, R.id.pt_initial_db };

有了这个:

 String[] columns = new String[] { c.getColumnName(1), c.getColumnName(2) };
    int[] to = new int[] {R.id.room_number_db, R.id.pt_initial_db };

答案 1 :(得分:2)

新错误表示您的数据库中没有表“DATABASE_PATIENT_TABLE”。从您的代码看起来是包含数据库中表的名称的字符串的静态字段名称,而不是数据库中表的名称。

在下面的代码中,您需要将“DATABASE_PATIENT_TABLE”更改为数据库中表的名称。

String db_sel = "SELECT id as _id, KEY_ROOM_NUMBER" +
",KEY_PATIENT_INITIAL FROM DATABASE_PATIENT_TABLE";

试试这个,看看它是否有效:

String db_sel = "SELECT id as _id, KEY_ROOM_NUMBER" +
",KEY_PATIENT_INITIAL FROM" +  DATABASE_PATIENT_TABLE;

对于原始错误,SimpleCursorAdapter必须包含_id字段。您对为游标提供动力的SQL Statment所做的更改应修复它,但您需要确保在SQL语句中具有正确的表名。

希望这有帮助。

答案 2 :(得分:0)

问题是固定的,主要的是我应该确保我总是用数据库的每个查询查询_id,但是如果我用cursor.getString(someIndex)来做,那么这会被误导为适配器我的情况是将第一列的内容作为rowid并尝试搜索该行。

虚空做rawQuery(),或使用“选择_id为_id”的东西是强制性的。我觉得这些事情有时会产生误导。

所以保持简单,下面是代码。 数据库代码

 public Cursor getAllRows_Patient_Db() 
{               
    return db.query(DATABASE_PATIENT_TABLE, new String[] {
            KEY_ROWID, 
            KEY_ROOM_NUMBER,
            KEY_PATIENT_INITIAL
            }, 
            null, 
            null, 
            null, 
            null, 
            null);
}

活动代码

    HospitalData = new Database(this);
    HospitalData.open();
    Cursor c = HospitalData.getAllRows_Patient_Db();


    startManagingCursor(c);

    String[] columns = new String[] {HospitalData.KEY_ROOM_NUMBER,HospitalData.KEY_PATIENT_INITIAL };
     int[] to = new int[] {  R.id.room_number_db, R.id.pt_initial_db };
     adapter = new SimpleCursorAdapter(this,R.layout.patient_db, c,columns,to);
     c.moveToNext();
     setListAdapter(adapter);