Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 按预期调用onCreate。但是没有创建表_Java_Android_Sqlite - Fatal编程技术网

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

Java 按预期调用onCreate。但是没有创建表,java,android,sqlite,Java,Android,Sqlite,所以我遇到了这个问题,这真的让我很恼火。我重写了扩展SQLiteOpenHelper的类的onCreate方法: @Override public void onCreate(SQLiteDatabase db) { super.onCreate(db); final String createAccTableCmd = ("CREATE TABLE IF NOT EXISTS " + ACCOUNTS_TABLE_NAME + " ( " + A

所以我遇到了这个问题,这真的让我很恼火。我重写了扩展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());
}
@覆盖
public void onCreate(SQLiteDatabase db){
super.onCreate(db);
最后一个字符串createAccTableCmd=(“如果不存在创建表”+帐户\表\名称+”(“+
帐户密钥ID+“整数主键ASC自动递增,”+
帐户\密钥\名称+“冲突时文本唯一忽略冲突时不为空忽略,”+
ACCOUNT_KEY_SELECTED+“冲突忽略时整数不为空,”+//以毫秒为单位
在冲突忽略上选中(“+ACCOUNT\u KEY\u SELECTED+”=0或“+ACCOUNT\u KEY\u SELECTED+”=1)+
" ) ");
最后一个字符串oneAndOnlyOneSelectedAccInsertTriggerCmd=“CREATE TRIGGER”+ONE和\仅\所选\触发器\插入\名称+“”+
“在“+科目表名称+”上插入后”+
“每行”+
“开始”+
“从“+ACCOUNTS_TABLE_NAME+”中删除,其中“+ACCOUNT_KEY_ID+”=新建。“+ACCOUNT_KEY_ID+”;”+
“结束”;
最后一个字符串oneAndOnlyOneSelectedUpdateTriggerCmd=“CREATE TRIGGER”+ONE和\仅\所选\触发器\更新\名称+“”+
更新“+帐户\表格\名称+”后+
“每行”+
“当(选择(总和(“+账户\密钥\ ID+”)1)”+
“开始”+
“更新”+科目表名称+“设置”+科目表键选中+”=0+
“更新”+科目表名称+“设置”+科目键选中+“=1,其中“+科目键ID+”=新建。“+科目键ID+”;”+
“结束”;
已同步(DB_锁){
db.beginTransaction();
db.execSQL(createAccTableCmd);
db.execSQL(一个且仅一个所选的AccInsertTriggerCmd);
db.execSQL(一个且仅一个selectedUpdateTriggerCmd);
addTableName(账户\表格\名称);
ContentValues cv=新的ContentValues();
cv.put(账户密钥ID,0);
cv.put(账户、关键字、名称);
cv.put(已选择帐户密钥,0);
Log.d(“调试”,如果插入时出错,则为-1:“+db.insert(ACCOUNTS\u TABLE\u NAME,”,cv));
Log.d(“调试”,“大小:”+db.query(ACCOUNTS\u TABLE\u NAME,null,null,null,null,ACCOUNT\u KEY\u ID+“ASC”).getCount();
db.setTransactionSuccessful();
db.endTransaction();
LBackupAgent.requestBackup(mContext);
}
Log.d(“调试”,“结束事务后的大小:”+db.query(ACCOUNTS\u TABLE\u NAME,null,null,null,ACCOUNT\u KEY\u ID+“ASC”).getCount();
}
人们预计其结果是:

  • -1如果插入时出错:0
  • 大小:0/*或1,如果选择将当前事务的未提交数据考虑在内,我对此不确定*/
  • 结束事务后的大小:1
当实际输出恰好为:

  • -1如果插入时出错:0
  • 尺寸:0
  • 结束事务后的大小:0
插入成功但选择返回0行怎么可能?
我用一个shell检查了表是否存在,但实际上它是空的,这可以解释为,在onCreate()完成之前,表似乎并不真正存在,这也证明了插入命令返回的0是正确的。我是否应该猜测这是某种设计约束,以确保onCreate只包括CREATE TABLE、CREATE TRIGGER和此类语句?如果我认为我的模式定义需要插入(如情况)?p> 尝试插入一些虚拟值,而不是下面的值:

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());

onCreate()
已在事务中运行,sqlite不支持嵌套事务。androidsqlite试图为嵌套事务提供一些支持,但这种支持是不完整的:实际的提交/回滚仅在最外层事务完成时执行。不要在
onCreate()
中使用事务。虽然这并不能真正解释您的输出。它不能解释输出,但很高兴知道,谢谢。使用“”列破解和硬编码的ContentValues对象仍然会产生相同的结果。我认为打印日志时,事务没有完成。事务完成后,尝试获取/记录数据。更新了应答器endtransaction之外还有另一个log命令,顺便说一下,这并不重要(请参见@laalto的评论)。不管怎样,通过shell检查(一旦onCreate确实完成)确实显示表也是空的。。你能试着移除触发器吗。我怀疑问题就在于此。已确认。第一个触发器缺少WHEN条件。