无法使用主键

时间:2017-07-04 13:53:57

标签: android sql sqlite cursor primary-key

我有这张桌子

private static final String SQL_CREATE_TABLE_TASKS = String.format("CREATE TABLE %s"
            +" (%s INTEGER PRIMARY KEY AUTOINCREMENT, %s TEXT, %s INTEGER, %s INTEGER, %s INTEGER)",
            DatabaseContract.TABLE_TASKS,
            TaskColumns._ID,
            TaskColumns.DESCRIPTION,
            TaskColumns.IS_COMPLETE,
            TaskColumns.IS_PRIORITY,
            TaskColumns.DUE_DATE
    );

此数据库的主键是_ID

public static final String _ID = "_id";

现在,问题在于:我使用游标查询数据库。

例如,如果我想检索主键为0的单行,我应该这样做:

String query = "SELECT " + DatabaseContract.TaskColumns.DESCRIPTION +
                ", " + DatabaseContract.TaskColumns.DUE_DATE +
                ", " + DatabaseContract.TaskColumns.IS_COMPLETE +
                ", " + DatabaseContract.TaskColumns.IS_PRIORITY +
                " FROM " + DatabaseContract.TABLE_TASKS +
                selection +
                " ORDER BY " +
                sortOrder +
                ";";
db.rawQuery(query, null);

string = "SELECT description, due_date, is_complete, is_priority FROM tasks WHERE _id = '0' ORDER BY is_complete ASC, is_priority DESC, due_date ASC;"

它应该将光标返回到表中所需的行

但是,正如你猜测的那样,我收到了一个错误:

  

致命的例外:主要

     

进程:com.google.developer.taskmaker,PID:4195 android.database.CursorIndexOutOfBoundsException:请求索引0,大小为0

如果我试图检索另一行,例如2,它会给我一个不同的行,就像一个随机的行。

如果我试图这样做:

cursor.getColumnIndex("_id");

获取主键行的索引,它将返回-1,这显然不存在于数据库中,-1表示sqlite上的空指针异常。

如果我正在访问

int colIndex = -1;
cursor.getInt(colIndex);

获取该行的主键,我收到错误。

遇到这个问题,我无法删除/更新/查询具有主键ID的特定行。我认为主键行以某种方式隐藏,我必须unlock它。

我甚至使用db.update/insert/query/delete但没有工作,所以我切换到原始查询以对其进行更多控制。

我必须非常快速地解决这个问题,感谢任何帮助。

感谢。

编辑#1:

我找到了一件事:

在查询数据库时,我已经增加了ID,所以如果需要第一项,它将查询id = 1而不是id = 0。现在,我对光标没有任何问题。 但是,当我尝试更新条目时,例如id = 2,第二个条目,没有任何反应。条目#2存在并显示在recyclerview中。它应该选中一个复选框,如果它是1.这是查询在数据库上执行的内容:

query = "UPDATE tasks SET is_complete = '1' WHERE _id = '2';";
db.rawQuery(query, null);

更新查询后,is_complete仍为0。

1 个答案:

答案 0 :(得分:0)

_id列为AUTOINCREMENT。这意味着您插入到表中的第一行将有_id=1
执行时:

"SELECT description, due_date, is_complete, is_priority FROM tasks WHERE _id = '0' ORDER BY is_complete ASC, is_priority DESC, due_date ASC;"

您将不会获得任何行,因为在您的表中没有_id=0的行,并且永远不会。
在ID之间可能也存在间隙,因为如果您删除说_id=3的行,则永远不会再有_id=3的另一行。

也许您在recyclerview适配器中使用了_id列中的值,这使事情搞砸了,因为适配器中该项的位置与其_id无关。