2011-12-08 60 views
2

我在android开发中使用SQLite。当我使用insert插入一行时,我得到了该行的编号。不过,我想要KEY_ID这是表的主键。我使用了下面的功能,但我得到了:如何从行号获取光标

Caused by: java.lang.IllegalStateException: get field slot from row 0 col -1 failed 
    at android.database.CursorWindow.getLong_native(Native Method) 
    at android.database.CursorWindow.getInt(CursorWindow.java:434) 
    at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:93) 
    at winterfarmer.timemama.DataBaseAdapter.insertData(DataBaseAdapter.java:89) 
    at winterfarmer.timemama.ManagerActivity.addNewRecord2DB(ManagerActivity.java:106) 
    at winterfarmer.timemama.ManagerActivity.addNewRecord(ManagerActivity.java:100) 
    at winterfarmer.timemama.ManagerActivity.addNewRecord2DB(ManagerActivity.java:106) 
    at winterfarmer.timemama.ManagerActivity.addNewRecord(ManagerActivity.java:100) 
    at winterfarmer.timemama.ManagerActivity.setRecordOK(ManagerActivity.java:92) 
    at winterfarmer.timemama.ManagerActivity.setRecord(ManagerActivity.java:78) 
    at winterfarmer.timemama.ManagerActivity.onActivityResult(ManagerActivity.java:64) 
    at android.app.Activity.dispatchActivityResult(Activity.java:3890) 
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3511) 

我该如何解决这个错误?

public int insertData(RecordInfo recordInfo) { 
    Log.d(TAG, "insertData"); 

    ContentValues initialValues = new ContentValues(); 

    initialValues.put(KEY_HOUR, recordInfo.hour); 
    initialValues.put(KEY_MINUTE, recordInfo.minute); 
    initialValues.put(KEY_REPEAT, recordInfo.repeat); 

    long rowId = db.insert(DB_ALARM_TABLE, null, initialValues); 
    assert rowId >= 0 : "insertData failed"; 
    Log.d(TAG, "insertData, rowId = " + rowId); 
    Cursor cur = db.rawQuery("SELECT last_insert_rowid() from " 
      + DB_ALARM_TABLE, null); 
    cur.moveToFirst(); 
    int colId = cur.getColumnIndex(KEY_ID); 
    Log.d(TAG, "insertData, colId = " + colId); 
    assert colId >= 0 : "insertData failed"; 
    return cur.getInt(colId); 
} 
+0

请上传您的完整堆栈跟踪。 –

+0

哪一个是你的适配器的第89行? – Guillaume

+0

为了将来的参考,请不要将堆栈跟踪或代码作为注释发布,它们不可读。改为编辑问题。 – NullUserException

回答

2

从光标DOC:

公共抽象INT getColumnIndex(字符串COLUMNNAME)

自:API等级1 返回从零开始指数为给定列 名,或-1如果列不存在。如果你希望列存在 使用getColumnIndexOrThrow(String)来代替,这将使错误更加清晰

因此,这将解释的问题要好。

总之,回到你的实际问题

的问题是,KEY_ID是不是你的选择查询(结果不会被命名为KEY_ID,即使值最初来自KEY_ID的结果列柱)。它只有一个列结果,因此索引列索引是没有意义的。 colId为0。你可以直接做:

Cursor cur = db.rawQuery("SELECT last_insert_rowid() from " 
     + DB_ALARM_TABLE, null); 
cur.moveToFirst(); 
return cur.getInt(0); 
+0

我创建表我们 – CodeBoy

+0

私有静态最后弦乐DB_CREATE = “CREATE TABLE” + DB_ALARM_TABLE \t \t \t + “(” + KEY_ID + “INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,” \t \t \t + KEY_HOUR +“INT NOT NULL ,“+ KEY_MINUTE +”INT NOT NULL,“ \t \t \t + KEY_REPEAT +”INT NOT NULL“+”)“; – CodeBoy

+0

对不起,我的第一个答案是不正确的,你可以看到我编辑它来解释你的真实问题 – Guillaume

0
int colId = cur.getColumnIndex(KEY_ID); 

我建议改变这

int colId = cur.getColumnIndexOrThrow(KEY_ID); 

如果列不存在,这似乎是可能的原因(如纪尧姆指出),你会得到更多的信息例外,并且比检查返回值-1更简单。

+0

是的..看来我不创建列KEY_ID – CodeBoy

+0

@CodeBoy:不,这不是你的问题,看到我的答案 - 你的问题是,你没有在你的查询中选择KEY_ID,你选择了last_insert_rowid() – Guillaume