我搜索了很多,很多关于这一点。但很少有帮助
问题是升级和降级数据库。 如果只是升级或降级,那很简单。
当升级,修改或添加表(保持数据,这很重要)时,降级时,删除已知表,然后重新创建它(数据丢失,无关紧要,因为降级不是用户的推荐操作,但是当用户降级完毕,应用程序无法崩溃)。
所以重要的是用户可能会降级然后升级。
考虑这种情况:
获得4个版本,有a1(低版本),a2,a3,a4(高版本)
a1 table1
a2 table1 table2(添加表,添加归档t2_2)
a3 table1 table2(添加字段t2_3)
a4 table1(添加字段t1_4)table2(添加字段t2_4)
如果安装总计新(不是升级或降级),所有版本都将在 onCreate 中创建自己的表。
如果升级,我们会升级表格或在 onUpgrade 中添加表格,如下所示:http://blog.adamsbros.org/2012/02/28/upgrade-android-sqlite-database/
如果降级,我们会删除并重新创建 onDowngrade 中相应版本中已知的表格。
例如,当a4-> a1时,删除table1并重新创建它; a4-> a2删除table1和table2,然后重新创建它们。
但是当用户执行此操作时会出现错误a4-> a1-> a3。
当a1升级到a3时,table2实际存在,因为当a4降级到a1时,它不会被删除(在a1中,它不会在以后的版本中添加新表)。我们会丢失数据,所以在升级时,我们无法删除表以重新创建表。因此,唯一的方法是修改表,假设我们知道表结构。问题出现在这里,在a4-> a1-> a3,a3不知道前面的表结构是什么。它简单地创建了table2(可能会出现错误,实际上是在实际使用中,可能会更复杂)
*我有一个想法来解决这个问题,在降级时删除所有表格。但是没有办法删除所有表格
删除数据库,我认为这可行,但现实是残酷的
降级时,我在onDowngrade中调用了 context.deleteDatabase(DB_NAME); 。然后调用表创建函数。它崩溃了。首先,我认为系统将重新创建数据库文件,实际上不是。*
我的问题是:
1.如何从sqlite中删除所有表
2.或者删除数据库时如何重新创建数据库。
任何人都解决了。
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.app.ActivityThread.installContentProviders(ActivityThread.java:4263)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4201)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.app.ActivityThread.access$1300(ActivityThread.java:137)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.os.Handler.dispatchMessage(Handler.java:99)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.os.Looper.loop(Looper.java:137)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.app.ActivityThread.main(ActivityThread.java:4819)
09-03 17:42:47.800: E/AndroidRuntime(19267): at java.lang.reflect.Method.invokeNative(Native Method)
09-03 17:42:47.800: E/AndroidRuntime(19267): at java.lang.reflect.Method.invoke(Method.java:511)
09-03 17:42:47.800: E/AndroidRuntime(19267): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-03 17:42:47.800: E/AndroidRuntime(19267): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-03 17:42:47.800: E/AndroidRuntime(19267): at dalvik.system.NativeStart.main(Native Method)
09-03 17:42:47.800: E/AndroidRuntime(19267): Caused by: android.database.sqlite.SQLiteException: cannot rollback - no transaction is active (code 1)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:548)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteSession.endTransactionUnchecked(SQLiteSession.java:439)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession.java:401)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:522)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:263)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
09-03 17:42:47.800: E/AndroidRuntime(19267): at com.sogou.appmall.db.MarketContentProvider.onCreate(SourceFile:36)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.content.ContentProvider.attachInfo(ContentProvider.java:1058)
09-03 17:42:47.800: E/AndroidRuntime(19267): at android.app.ActivityThread.installProvider(ActivityThread.java:4634)
09-03 17:42:47.800: E/AndroidRuntime(19267): ... 12 more
09-03 17:42:49.020: E/Trace(19302): error opening trace file: No such file or directory (2)
09-03 17:42:49.960: E/Trace(19318): error opening trace file: No such file or directory (2)
稍后我会通过这种方式获取数据库的所有表,然后删除表并重新创建它们。
SQLiteDatabase db = openOrCreateDatabase(MarketDBHelper.DB_NAME,
Context.MODE_PRIVATE, null);
Cursor cursor = db
.rawQuery(
"select name from sqlite_master where type='table' order by name",
null);
while (cursor.moveToNext()) {
// 遍历出表名
String name = cursor.getString(0);
Log.i("MarketDBHelper", name);
}
if(cursor!=null&&!cursor.isClosed()){
cursor.close();
}
谢谢大家。
答案 0 :(得分:4)
在DB上执行原始SQL请求以删除表:
DROP TABLE table_name;
表示数据库中的每个表。
OR
DROP TABLE table_name CASCADE;
要删除一个表以及依赖它的所有其他对象,请使用其中一个。
Cursor cursor = getReadableDatabase().rawQuery("DROP TABLE ?", new String[] { "MY_TABLE" });
答案 1 :(得分:4)
方法:1:
PRAGMA writable_schema = 1;
delete from sqlite_master where type = 'table';
PRAGMA writable_schema = 0;
方法:2:
select 'drop table ' || name || ';' from sqlite_master where type = 'table';
这是一个将为您删除表的脚本。对于索引,只需将表替换为索引。
您可以使用where部分中的其他子句来限制选择哪些表或索引(例如"以及名称glob' pax _ *'"对于那些以&#开头的人34; PAX _"。)
您可以将此脚本的创建与在简单的bash(或cmd.exe)脚本中运行它一起使用,因此只能运行一个命令。
如果您不关心数据库中的任何信息,我认为您可以删除存储在硬盘中的文件 - 这可能更快。我从来没有对此进行过测试,但我不明白为什么它不起作用。
参考bellow drop all table命令链接: