我正在尝试将sqlite中的现有数据迁移到会议室数据库中。
我提供了迁移规则。
This is the migration rule:
private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE temp_account (\n"+
" _id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,"
+ "name TEXT NOT NULL UNIQUE, "
+ "number TEXT DEFAULT 0, "
+ "balance REAL DEFAULT 0 NOT NULL, "
+ "account_type TEXT);");
database.execSQL("INSERT INTO temp_account( name,number,balance,account_type) " +
"SELECT name,number,balance,account_type FROM account");
database.execSQL("DROP TABLE account");
database.execSQL("ALTER TABLE temp_account RENAME TO account;");
;
Below is my original table which I want to migrate:
"CREATE TABLE account (\n"+
" _id INTEGER PRIMARY KEY AUTOINCREMENT ,"
+ "name TEXT NOT NULL UNIQUE, "
+ "number TEXT DEFAULT 0, "
+ "balance REAL , "
+ "account_type TEXT);");
虽然它可以在大多数设备上运行,但该应用在少数设备上崩溃。崩溃并非特定于任何设备或android版本。以下是Google的错误报告:
java.lang.RuntimeException:
at android.os.AsyncTask$3.done (AsyncTask.java:354)
at java.util.concurrent.FutureTask.finishCompletion (FutureTask.java:383)
at java.util.concurrent.FutureTask.setException (FutureTask.java:252)
at java.util.concurrent.FutureTask.run (FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
at java.lang.Thread.run (Thread.java:764)
Caused by: android.database.sqlite.SQLiteConstraintException: at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
我们非常感谢您的帮助。
答案 0 :(得分:1)
我认为问题在于原始表中的某些余额是 NULL ,并且在插入新添加的 NOT NULL 时约束冲突。
您可以通过用任一
替换 balance 来解决此问题CASE WHEN balance IS NULL THEN 0 ELSE balance END
或coalesce(balance,0)
两者都将有效地使用0而不是NULL的值。
例如
database.execSQL("INSERT INTO temp_account( name,number,balance,account_type) " +
"SELECT name,number,
coalesce(balance,0),
account_type FROM account");
或
database.execSQL("INSERT INTO temp_account( name,number,balance,account_type) " +
"SELECT name,number,
CASE WHEN balance IS NULL THEN 0 ELSE balance END,
account_type FROM account");