【发布时间】:2019-01-09 23:57:52
【问题描述】:
我将我的数据库从 SQLiteOpenHelper 迁移到 Room。
我有一张表要更改,我们称之为"my_table"。
其简化的创建语句:
CREATE TABLE `my_table`
(`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`title` TEXT
)
在升级期间,我添加了新列 type INTEGER NOT NULL(我还添加了外键并进行了其他重大更改,这就是创建新表而不是更改现有表的原因):
CREATE TABLE "new_table"
(`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`title` TEXT,
`type` INTEGER NOT NULL
)
然后我想将数据从my_table 复制到new_table 并设置type 列的值。
SQL 语句:
INSERT INTO new_table (title)
SELECT title FROM my_table;
UPDATE new_table SET type = 1;
DROP TABLE my_table;
ALTER TABLE new_table RENAME TO my_table;
Android 迁移:
public static final Migration MIGRATION_TEST = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
// Create new table
database.execSQL("CREATE TABLE new_table (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `type` INTEGER NOT NULL)");
// Copy some data
database.execSQL("INSERT INTO new_table (title) SELECT title FROM old_table"); // constraint violation
// Insert default value into the measures column
database.execSQL("UPDATE new_table SET type = 1");
// Delete old table
database.execSQL("DROP TABLE old_table");
// Rename new table
database.execSQL("ALTER TABLE new_table RENAME TO my_table");
}
};
显然我得到NOT NULL constraint failed: new_table.type 错误:
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: new_table.type (code 1299)
Error Code : 1299 (SQLITE_CONSTRAINT_NOTNULL)
Caused By : Abort due to constraint violation.
(NOT NULL constraint failed: new_table.type (code 1299))
我可以通过更改新表的创建语句并为type 列设置默认值来避免它。
CREATE TABLE "new_table"
(`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`title` TEXT,
`type` INTEGER NOT NULL DEFAULT 1
)
但我不想这样做,因为 Room 不支持开箱即用的默认值,并且为了避免将来在向表中插入新值时出现错误。
在将数据插入新表时,是否有任何解决方法可以避免此错误?
【问题讨论】:
标签: android sql sqlite android-room