onCreate按预期调用。但是没有创建表格

时间:2014-08-22 09:24:32

标签: java android sqlite

所以我遇到了这个让我烦恼的问题。我重写了我的类的onCreate方法,扩展了SQLiteOpenHelper:

    @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,如果select考虑到当前事务未提交的数据,我不确定这个* /
  • 结束交易后的尺寸:1

当实际输出恰好是:

  • -1如果插入错误:0
  • 尺寸:0
  • 结束交易后的尺寸:0

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

1 个答案:

答案 0 :(得分:1)

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

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发送,而是将其作为&#34;&#34;发送。它将确保即使值为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());