我的应用程序中有一个SQLite数据库,我正在尝试将其从版本4迁移到版本5.如果我卸载然后重新安装,则应用程序正常工作。为了便于理解,我将恢复这个问题。
在v4中我创建了这个表:
private static final String CREATE_TABLE = "CREATE TABLE " + Globals._TABLE +
" ( " +
Globals._ID + " INTEGER PRIMARY KEY, " +
Globals._PRIORITY + " INTEGER, " +
Globals._FUNC_NAME + " TEXT " +
");";
在第5版中,我删除了_PRIORITY和_FUNC_NAME列。我还使用MySQL DB提供的索引编制索引。我需要创建一种在内部索引DB的方法。所以我创建了这样的表:
private static final String CREATE_TABLE =
"CREATE TABLE IF NOT EXISTS " + Globals._TABLE +
" ( " +
Globals._SQLITE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
Globals._UPLOADED + " INTEGER, " +
Globals._ID + " INTEGER DEFAULT 0 " +
");";
我的OnCreate方法就是这样,并没有抛出任何错误:
@Override
public void onCreate( SQLiteDatabase db )
{
try
{
db.execSQL( CREATE_TABLE );
}
catch( SQLException e )
{
e.printStackTrace( );
}
}
我正在使用此查询删除表:
private static final String DROP_TABLE = "DROP TABLE IF EXISTS " + Globals._TABLE;
我的OnUpgrade方法就是这样,也不会抛出错误:
SQLiteMigratorV5 migrator = new SQLiteMigratorV5( mContext, db );
switch( newVersion )
{
case 5:
migrator.saveData( );
break;
default:
break;
}
try
{
db.execSQL( DROP_TABLE );
}
catch( SQLException e )
{
e.printStackTrace( );
}
onCreate( db );
switch( newVersion )
{
case 5:
migrator.restoreData( );
break;
default:
break;
}
}
调试应用程序我可以看到onUpgrade和OnCreate都被调用。我的负责迁移的类保存了所有数据,并且应该将所有数据恢复到新表中。调试我也可以说旧表中的所有行都正确地插入到新表中。
当我尝试访问此数据时会出现问题。我有另一个表,通过id索引第一个表中的元素,我还重新创建了另一个表,我需要使用SQLite id进行索引。所以我正在执行rawQuery并检索游标:
String query = "SELECT * FROM " + Globals._TABLE + " WHERE " + Globals._ID + " = '1'";
Cursor cursor = mDB.rawQuery( query, null );
当我检查游标列时,我找不到_SQLITE_ID既没有_UPLOADED但是我可以找到_PRIORITY和_FUNC_NAME,当我尝试在我的另一个表中使用新插入的行_SQLITE_ID时,这会导致我出错。
for( cursor.moveToFirst( ); ! cursor.isAfterLast( ); cursor.moveToNext( ) )
{
setSQLiteId( cursor.getInt( cursor.getColumnIndex( Globals._SQLITE_ID ) ) );
...
}
这段代码引出了我的错误:
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
我不止一次检查了所有内容,我无法理解发生了什么,我唯一的假设是旧表没有被删除而新的表没有被创建因为CREATE TABLE IF不存在。
任何人都可以告诉我如何解决这个问题?
好的,我解决了这个问题,但我仍然没有解释
我的onUpgrade以这种方式调用:storesData>删除表>创建表格>恢复数据。
在我的商店功能中,我有这个功能:
public List< Client > getClientsWhereV4( String statement )
{
if( statement == null )
{
statement = "";
}
String query = "SELECT * FROM " + Globals._TABLE + " " + statement;
Cursor cursor = mDB.rawQuery( query, null );
List< Client > clientList = new ArrayList<>( );
for( cursor.moveToFirst( ); ! cursor.isAfterLast( ); cursor.moveToNext( ) )
{
Client client = new Client( mContext );
// Already ignoring deleted columns
client.setId( cursor.getInt( cursor.getColumnIndex( Globals._ID ) ) );
clientList.add( client );
}
cursor.close( );
return clientList;
}
这是我的恢复功能:
public List< Client > getClientsWhereV5( String statement )
{
if( statement == null )
{
statement = "";
}
String query = "SELECT * FROM " + Globals._TABLE + " " + statement;
Cursor cursor = mDB.rawQuery( query, null );
List< Client > clientList = new ArrayList<>( );
for( cursor.moveToFirst( ); ! cursor.isAfterLast( ); cursor.moveToNext( ) )
{
Client client = new Client();
setSQLiteId( cursor.getInt( cursor.getColumnIndex( Globals.CLIENT_SQLITE_ID ) ) );
if( cursor.getInt( cursor.getColumnIndex( Globals.CLIENT_UPLOADED ) ) == 1 )
{
setUploaded( true );
}
else
{
setUploaded( false );
}
setId( cursor.getInt( cursor.getColumnIndex( Globals.CLIENT_ID ) ) );
clientList.add( client );
}
cursor.close( );
return clientList;
}
如果商店查询等于还原查询,则会发生错误,例如:
// v4
String query = "SELECT * FROM " + Globals._TABLE + " " + statement;
// v5
String query = "SELECT * FROM " + Globals._TABLE + " " + statement;
如果有任何差异,一个人有一个空间或类似的东西,它可以正常工作。所有变量都是函数的局部变量,我关闭了游标,我不知道发生了什么。
答案 0 :(得分:0)
我认为错误是由于光标的位置,
尝试使用cursor.moveToFirst()
首先将光标移动到返回数据的第一行:
if (cursor.moveToFirst()) {
// Do your data access here,
// like cursor.getInt(...)
}
希望这有帮助。
答案 1 :(得分:-1)
while(cursor.moveToNext){
//do something.
// access your data from table here.
}