我正在制作一个Android应用程序来学习SQLite数据库。我有一个函数应该将用户的移动数据从加速度计写入数据库。使用以下命令创建数据库:
db.execSQL("create table if not exists data(ID integer primary key autoincrement, "+
"lat integer, long integer, "+
"movement real, "+
"time text);");
并且每2秒调用写入DB的函数:
void insertTable(float mov)
{
db.beginTransaction();
try
{
// this part gets the current time
Calendar now = Calendar.getInstance();
String date = now.get(Calendar.HOUR_OF_DAY)+":"+now.get(Calendar.MINUTE)+":"+now.get(Calendar.SECOND)+
"."+now.get(Calendar.MILLISECOND)+" "+now.get(Calendar.DAY_OF_MONTH)+"/"+now.get(Calendar.MONTH)+
"/"+now.get(Calendar.YEAR);
db.execSQL("insert into data(movement ,time) values ("+
mov+",'"+date+"');");
Cursor c1 = db.rawQuery("select * from data", null);
// this happens after the 5th iteration and the app crashes
if(numRefreshes>5) c1.moveToPosition(2);
// this happens the first 5 iterations of this function
else c1.moveToPosition(0);
// get time and date and show it on the screen
String datum = c1.getString(4);
c1.close();
dbResult.setText(datum);
// keep track of how many times this function has been called
numRefreshes++;
}
catch(SQLiteException e)
{
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
finally
{
db.endTransaction();
}
}
如您所见,调用此函数的前5次将从表格的第1行打印日期。它始终显示插入的最后行的值。我想这很好。 但是在第5次之后,当我尝试读取第3行的日期值时,它崩溃并且LogCat说:
FATAL EXCEPTION: main
android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
所以我假设SQLite每次都会覆盖我以前的行。我做错了什么?
答案 0 :(得分:2)
看起来您没有调用将事务设置为成功的方法。
您需要在db.setTransactionSuccessful()
numRefreshes++;
如果你查看db.beginTransaction()
的java文档,你会发现
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
如果没有setTransactionSuccessful,您将回滚所做的任何插入