95

在 SQLite 中删除所有表的命令是什么?

同样,我想删除所有索引。

4

11 回答 11

92

虽然确实没有 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;
于 2009-02-14T01:08:38.190 回答
89

我认为您不能一次删除所有表,但您可以执行以下操作来获取命令:

select 'drop table ' || name || ';' from sqlite_master
    where type = 'table';

其输出是一个脚本,它将为您删除表。对于索引,只需将表替换为索引即可。

您可以使用该where部分中的其他子句来限制选择哪些表或索引(例如“ and name glob 'pax_*'”用于以“pax_”开头的那些)。

您可以将此脚本的创建与在一个简单的 bash(或 cmd.exe)脚本中运行它结合起来,这样只需运行一个命令。

如果您不关心数据库中的任何信息,我认为您可以删除它存储在硬盘上的文件 - 这可能更快。我从来没有测试过这个,但我不明白为什么它不起作用。

于 2009-02-08T10:42:27.360 回答
36
rm db/development.sqlite3
于 2009-02-09T03:41:15.893 回答
22

我对 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);
}
于 2013-04-27T09:58:43.457 回答
5

使用 pysqlite:

tables = list(cur.execute("select name from sqlite_master where type is 'table'"))

cur.executescript(';'.join(["drop table if exists %s" %i for i in tables]))
于 2014-11-16T17:48:04.740 回答
4

我想添加其他涉及删除表而不删除文件的答案,您也可以执行这些答案delete from sqlite_sequence来重置自动增量序列。

于 2012-02-09T12:03:05.843 回答
3

一旦你删除了所有表(当表消失时索引将消失),据我所知,SQLite 数据库中没有任何内容,尽管文件似乎没有缩小(从我刚刚做的快速测试)。

所以删除文件似乎是最快的——它应该在你的应用程序尝试访问 db 文件时重新创建。

于 2009-02-08T14:27:08.123 回答
2

我在 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();
    }
}
于 2017-08-31T18:08:14.503 回答
1

我不能说这是最防弹或最便携的解决方案,但它适用于我的测试脚本:

.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”命令(将命令发送到临时文件),将输出设置回标准输出,然后执行文件中的命令,最后删除文件。

于 2018-01-18T20:22:16.740 回答
0

或者在 shell 提示符下,只需两行,没有命名的临时文件,假设 $db 是 SQLite 数据库名称:

echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
    sqlite3 -readonly "$db" | sqlite3 "$db"
于 2019-10-11T22:45:35.213 回答
0

要删除视图,请添加“视图”关键字:

delete from sqlite_master where type in ('view', 'table', 'index', 'trigger');
于 2021-01-05T11:06:36.730 回答