在SQLite中删除所有表的命令是什么?
同样,我想删除所有索引。
Answers:
我不认为您可以一键删除所有表,但是可以执行以下操作来获取命令:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
此输出是一个脚本,它将为您删除表。对于索引,只需将表替换为索引。
您可以在本where
节中使用其他子句来限制选择的表或索引(例如,and name glob 'pax_*'
对于以“ pax_”开头的表或索引,则为“”)。
您可以在一个简单的bash(或cmd.exe)脚本中将此脚本的创建与运行结合起来,因此仅需运行一个命令。
如果您不关心数据库中的任何信息,我想您可以删除存储在硬盘上的文件,这可能会更快。我从来没有测试过,但我看不出为什么它不起作用。
确实没有任何DROP ALL TABLES命令,但是您可以使用以下命令集。
注意:这些命令可能会破坏数据库,因此请确保您有备份
PRAGMA writable_schema = 1;
delete from sqlite_master where type in ('table', 'index', 'trigger');
PRAGMA writable_schema = 0;
然后,您想要恢复已删除的空间
VACUUM;
并进行良好测试,以确保一切正常
PRAGMA INTEGRITY_CHECK;
delete from sqlite_master where type in ('table', 'index', 'trigger')
。
rm db/development.sqlite3
我在使用SQLite和Android时遇到了同样的问题。这是我的解决方案:
List<String> tables = new ArrayList<String>();
Cursor cursor = db.rawQuery("SELECT * FROM sqlite_master WHERE type='table';", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String tableName = cursor.getString(1);
if (!tableName.equals("android_metadata") &&
!tableName.equals("sqlite_sequence"))
tables.add(tableName);
cursor.moveToNext();
}
cursor.close();
for(String tableName:tables) {
db.execSQL("DROP TABLE IF EXISTS " + tableName);
}
我想添加到其他一些涉及删除表而不删除文件的答案中,也可以执行delete from sqlite_sequence
以重置自动递增序列。
一旦删除了所有表(表走后索引将消失),就我所知,SQLite数据库中什么也没有,尽管文件似乎没有收缩(通过快速测试,我刚刚做了) )。
因此,删除文件似乎是最快的-当您的应用尝试访问db文件时,应该重新创建该文件。
我在Android中遇到了这个问题,并且写了一种类似于it-west的方法。
因为我AUTOINCREMENT
在表中使用了主键,所以有一个名为的表sqlite_sequence
。当例程尝试删除该表时,SQLite将崩溃。我也无法捕捉到异常。通过查看https://www.sqlite.org/fileformat.html#internal_schema_objects,我了解到可能会有一些我不想删除的内部模式表。文档说这些表中的任何一个都以sqlite_开头,所以我写了这种方法
private void dropAllUserTables(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
//noinspection TryFinallyCanBeTryWithResources not available with API < 19
try {
List<String> tables = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
tables.add(cursor.getString(0));
}
for (String table : tables) {
if (table.startsWith("sqlite_")) {
continue;
}
db.execSQL("DROP TABLE IF EXISTS " + table);
Log.v(LOG_TAG, "Dropped table " + table);
}
} finally {
cursor.close();
}
}
我不能说这是最防弹或可移植的解决方案,但是它适用于我的测试脚本:
.output /tmp/temp_drop_tables.sql
select 'drop table ' || name || ';' from sqlite_master where type = 'table';
.output stdout
.read /tmp/temp_drop_tables.sql
.system rm /tmp/temp_drop_tables.sql
这部分代码将输出重定向到一个临时文件,构造我要运行的“ drop table”命令(将命令发送到temp文件),将输出设置回标准输出,然后从该文件中执行命令,最后删除文件。