SQLiteDatabase.insertOrThrow不会抛出但不会插入数据

emi*_*rax 5 sqlite android

我正在努力熟悉Android及其数据库API.我创建了一个继承自SQLiteOpenHelper的类,这就是我在数据库中创建表的方法

@Override
public void onCreate(SQLiteDatabase db) {

    try {
        db.execSQL("CREATE TABLE " + FUELS_TABLE_NAME + " ("
                + "_ID INTEGER PRIMARY KEY AUTOINCREMENT, "
                + "DATE_OF_FUELS DATE DEFAULT CURRENT_TIME,"
                + "SELLER_POSITION TEXT DEFAULT 'unknown',"
                + "AMOUNT REAL"
                + ");"
        );
    } catch (SQLException e) {
        Log.e(DATABASE_NAME, e.toString());
    }
}
Run Code Online (Sandbox Code Playgroud)

用于向DB添加数据的函数是在同一类中实现的以下内容

public void addNewFuel(float amount) {

    // Create the content to insert into the database
    ContentValues newEntry = new ContentValues();
    newEntry.put("amount", amount);

    // Get database handler
    try {
        db = getWritableDatabase();
    } catch (SQLException e) {
        Log.e(DATABASE_NAME, e.toString());
        return;
    }

    // Begin transaction and insert data
    long returnedValue;
    db.beginTransaction();
    try {
        returnedValue = db.insertOrThrow(FUELS_TABLE_NAME, null, newEntry);
        Log.v(DATABASE_NAME, "return value " + returnedValue);
    } catch (SQLException e) {
        Log.e(DATABASE_NAME, e.toString());
    } finally {
        db.endTransaction();
    }

    db.close();
}
Run Code Online (Sandbox Code Playgroud)

但显然没有添加任何数据.returnValue始终为1.方法不抛出,当我用adb拉出数据库并查看它时,内容完全是空的.

我只是无法理解我所缺少的东西.

任何建议将不胜感激.

谢谢,S

小智 29

McStretch的回答是不正确的.getWritableDatabase()不为您的代码创建事务,来自文档的引用行指的是用于onCreate和onUpgrade方法的事务,这意味着您不需要在这些方法中添加事务代码.您仍然需要为需要事务的任何其他方法添加事务代码.

emitrax的代码无法正常工作,因为db.setTransactionSuccessful()没有被调用,这意味着事务将被回滚db.endTransaction().


McS*_*tch -3

请参阅 benritz 的答案以获得正确的解决方案。这个答案是不正确的,但不幸的是我无法删除它,因为它是一个已接受的帖子。

/*******不正确!!

由于您继承自 SQLiteOpenHelper,因此您的调用getWritableDatabase()已经启动了数据库事务。从SQLiteOpenHelper API

事务用于确保数据库始终处于合理状态。

因此您不需要调用db.beginTransaction()db.endTransaction()。那些无关的事务调用会弄乱您的插入。我将相同的场景插入到我的项目中,发现使用这些事务方法时返回相同的索引(在我的例子中为 6)。当我删除呼叫时,我得到了想要的结果(插入了多条记录)。

不正确!!******/

  • 这实在是太奇怪了!SQLiteOpenHelper 的源代码当然不会打开除数据库创建和更新之外的任何事务。因此,在 getWriteableDatabase() 调用返回后,数据库没有活动的事务!要么确实出了什么问题,要么这个答案是假的。 (5认同)