我在一个"sqlite"数据库上运行了一个SQL查询,该数据库在调用时引发了以下异常:"java.lang.IllegalStateException:get-field slot from row 0 col 0 failed"
db.rawQuery( "SELECT data FROM session_data WHERE session_id = ?", new String[] { String.format("%d", session_id) } );
if (!cursor.moveToFirst()) return;
bytes[] bytes = cursor.getBlob(0);
该列存在,如果我使用adb shell sqlite3 /path/to/database.db
登录,我可以成功执行相同的查询。
结果光标显示有1行被选中,其中1列的名称为"data"。blob的大小大约是1.5 MB——可能是这样吗?我已经验证了cursor.GetColumnIndex("data")
返回0,因此该列存在。
这是在Android 2.1 SDK上运行的。有什么想法吗?
问题是blob太大。如果blob大小超过1兆字节,则cursor.getBlob(0)
似乎会失败。分段读取blob解决了我的问题:
// get length of blob data
Cursor cursor = db.rawQuery( "SELECT LENGTH(data) AS len FROM table WHERE id = ?", etc);
if (cursor == null || !cursor.moveToFirst()) throw new Exception("failed");
int size = cursor.getInt(cursor.getColumnIndexOrThrow("len"));
cursor.close();
// read a segment of the blob data
cursor = db.rawQuery( "SELECT SUBSTR(data,0,500000) AS partial FROM table WHERE id = ?", etc);
if (cursor == null || !cursor.moveToFirst()) throw new Exception("failed");
byte[] partial = cursor.getBlob(cursor.getColumnIndexOrThrow("partial"));
cursor.close();
// copy partial bytes, repeat until the whole length has been read...
我假设您持有对rawQuery
中光标的引用。在从光标获得任何值之前,您需要调用cursor.moveToFirst()
,因为cursor
最初位于-1。正确的方法是:
Cursor cursor = db.rawQuery( "SELECT data FROM session_data WHERE session_id = ?", new String[] { String.format("%d", session_id) } );
if(cursor!= null && cursor.moveToFirst()){ // checking if the cursor has any rows
bytes[] bytes = cursor.getBlob(0);
}
并确保数据库中的列是blob
类型的