如何在android中删除Sqlite中的所有表

时间:2014-09-03 09:55:25

标签: android sqlite downgrade

我搜索了很多,很多关于这一点。但很少有帮助 问题是升级和降级数据库如果只是升级或降级,那很简单。 当升级,修改或添加表(保持数据,这很重要)时,降级时,删除已知表,然后重新创建它(数据丢失,无关紧要,因为降级不是用户的推荐操作,但是当用户降级完毕,应用程序无法崩溃)。
所以重要的是用户可能会降级然后升级。

考虑这种情况:
获得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();
                    } 

谢谢大家。

2 个答案:

答案 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命令链接:

Drop all tables command