所以我有这个问题,真让我讨厌。我重写了扩展SQLiteOpenHelper的类的onCreate方法:

    @Override
public void onCreate(SQLiteDatabase db) {
    super.onCreate(db);
    final String createAccTableCmd = ("CREATE TABLE IF NOT EXISTS " + ACCOUNTS_TABLE_NAME + " ( " +
            ACCOUNT_KEY_ID + " INTEGER PRIMARY KEY ASC AUTOINCREMENT, " +
            ACCOUNT_KEY_NAME + " TEXT UNIQUE ON CONFLICT IGNORE NOT NULL ON CONFLICT IGNORE, " +
            ACCOUNT_KEY_SELECTED + " INTEGER NOT NULL ON CONFLICT IGNORE, " + //THIS IS IN MILLISECONDS
            "CHECK (" + ACCOUNT_KEY_SELECTED + " = 0 OR " + ACCOUNT_KEY_SELECTED + " = 1) ON CONFLICT IGNORE" +
            " ) ");
    final String oneAndOnlyOneSelectedAccInsertTriggerCmd = "CREATE TRIGGER " + ONE_AND_ONLY_ONE_SELECTED_TRIGGER_INSERT_NAME + " " +
            "AFTER INSERT ON " + ACCOUNTS_TABLE_NAME + " " +
            "FOR EACH ROW " +
            "BEGIN " +
            "DELETE FROM " + ACCOUNTS_TABLE_NAME + " WHERE " + ACCOUNT_KEY_ID + " = NEW." + ACCOUNT_KEY_ID + "; " +
            "END";
    final String oneAndOnlyOneSelectedUpdateTriggerCmd = "CREATE TRIGGER " + ONE_AND_ONLY_ONE_SELECTED_TRIGGER_UPDATE_NAME + " " +
            "AFTER UPDATE ON " + ACCOUNTS_TABLE_NAME + " " +
            "FOR EACH ROW " +
            "WHEN (SELECT(SUM(" + ACCOUNT_KEY_ID + ")) <> 1) " +
            "BEGIN " +
            "UPDATE " + ACCOUNTS_TABLE_NAME + " SET " + ACCOUNT_KEY_SELECTED + " = 0; " +
            "UPDATE " + ACCOUNTS_TABLE_NAME + " SET " + ACCOUNT_KEY_SELECTED + " = 1 WHERE " + ACCOUNT_KEY_ID + " = NEW." + ACCOUNT_KEY_ID + "; " +
            "END";
    synchronized (DB_LOCK) {
        db.beginTransaction();
        db.execSQL(createAccTableCmd);
        db.execSQL(oneAndOnlyOneSelectedAccInsertTriggerCmd);
        db.execSQL(oneAndOnlyOneSelectedUpdateTriggerCmd);
        addTableName(ACCOUNTS_TABLE_NAME);
        ContentValues cv = new ContentValues();
        cv.put(ACCOUNT_KEY_ID, 0);
        cv.put(ACCOUNT_KEY_NAME, "name");
        cv.put(ACCOUNT_KEY_SELECTED, 0);
        Log.d("debug", "-1 if error on insert: " + db.insert(ACCOUNTS_TABLE_NAME, "", cv));
        Log.d("debug", "Size: " + db.query(ACCOUNTS_TABLE_NAME, null, null, null, null, null, ACCOUNT_KEY_ID + " ASC").getCount());
        db.setTransactionSuccessful();
        db.endTransaction();
        LBackupAgent.requestBackup(mContext);
    }
    Log.d("debug", "Size after ending the transaction: " + db.query(ACCOUNTS_TABLE_NAME, null, null, null, null, null, ACCOUNT_KEY_ID + " ASC").getCount());
}


可以预期的结果是:


-1如果插入错误:0
大小:0 / *或1,如果选择考虑了当前事务未提交的数据,则我不确定* /
结束交易后的大小:1


当实际输出恰好是:


-1如果插入错误:0
大小:0
结束交易后的大小:0


如何成功插入但选择返回0行?
我已经检查了外壳是否存在该表,但实际上它是空的,这可以用以下事实来解释:在onCreate()完成之前,该表似乎并不存在,并证明了由0返回的0插入命令。我是否应该猜测这种设计约束,以确保onCreate仅包含CREATE TABLE,CREATE TRIGGER和此类语句?如果我认为我的模式定义需要插入(情况如此)怎么办?

最佳答案

尝试插入一些虚拟值,而不是下面的内容:

ContentValues defaultAcc = mapAccountToStorable(defaultAccDataModel = new AccountListRecyclerAdapter.AccountDataModel(
                        LBudgetUtils.getInt(mContext, "default_account_id"),
                        LBudgetUtils
                                .getString(mContext, "default_account_name"),
                        mContext.getResources().getBoolean(
                                R.bool.default_account_selected)));


而不是将nullColumnHack发送为null,而是将其发送为“”。即使值是null,也将确保在表中创建一行。

db.insert(ACCOUNTS_TABLE_NAME, "", defaultAcc)


请尝试以下方法:

    db.beginTransaction();
    db.execSQL(createAccTableCmd);
    db.execSQL(oneAndOnlyOneSelectedAccInsertTriggerCmd);
    db.execSQL(oneAndOnlyOneSelectedUpdateTriggerCmd);
    db.setTransactionSuccessful();
    db.endTransaction();

    db.beginTransaction();
    addTableName(ACCOUNTS_TABLE_NAME);
    AccountListRecyclerAdapter.AccountDataModel defaultAccDataModel;
    ContentValues defaultAcc = mapAccountToStorable(defaultAccDataModel = new AccountListRecyclerAdapter.AccountDataModel(LBudgetUtils.getInt(mContext, "default_account_id"), LBudgetUtils.getString(mContext, "default_account_name"), mContext.getResources().getBoolean(R.bool.default_account_selected)));
    Log.d("debug", "-1 if error on insert: " + db.insert(ACCOUNTS_TABLE_NAME, null, defaultAcc));
    db.setTransactionSuccessful();
    db.endTransaction();


    Log.d("debug", "Size: " + db.query(ACCOUNTS_TABLE_NAME, null, null, null, null, null, ACCOUNT_KEY_ID + " ASC").getCount());

关于java - 如预期那样调用onCreate。但是没有创建表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25443680/

10-13 04:32