0

很久以来我一直被困在一个点上,即使用

 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;

实际上我必须用键值更改声明的字符串

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 的方式

数据库表

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

原来是

   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)

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

4

3 回答 3

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 语句所做的更改应该可以修复它,但您需要确保 SQL 语句中的表名正确。

希望这可以帮助。

于 2011-07-04T17:58:46.107 回答
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 };
于 2011-07-04T16:16:24.123 回答
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);
于 2011-07-05T20:47:52.677 回答