删除所有表命令


Answers:


82

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

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

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

您可以在本where节中使用其他子句来限制选择的表或索引(例如,and name glob 'pax_*'对于以“ pax_”开头的表或索引,则为“”)。

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

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


谢谢。非常奇怪的是,没有简单的命令,而是这个hacky SQL查询。
alamodey

7
好了,得到一个空的SQLite数据库的最简单的方法就是删除文件,然后连接到它..
约翰·福希

2
因此,我的最后一段是@JF。
paxdiablo,

连接到表的触发器会发生什么?
rds 2015年

@rds,当您删除表时,该表的所有触发器也会被删除。在触发器不可能触发时保留触发器(因为该表不再存在)几乎没有意义。
paxdiablo

80

确实没有任何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;

1
如何在onUpgrade()中执行它们?
AZ_

只需执行DDL,就足够了
Noah

万一出于某种疯狂的原因,其他人有这个问题,上面的方法确实可以删除Titanium Mobile的Database API中的所有表。
莱利·达顿

2
令人难以置信的聪明。我们本地开发的增量升级系统只能执行比较版本的脚本,此技巧不需要任何改进:)
Ivan G.

3
注意:在第二次尝试清理数据库时(至少使用最新的sqlite),这可能会引起奇怪的“数据库文件格式错误”问题,但如果使用,则似乎可以正常工作delete from sqlite_master where type in ('table', 'index', 'trigger')
mlvljr 2012年

35
rm db/development.sqlite3

是的,这确实删除了数据库,但是在sqlite中除了表还有其他东西;有关详细信息,请参见我的完整答案
Noah

9
如果数据库打开了多个连接,则将无法使用。在仅删除名称的* nix上,连接将继续使用未命名的数据库文件,直到它们关闭其句柄为止。如果要重写模式(删除所有表,创建新表),则会遇到麻烦。
jbarlow

3
这不应是可接受的答案,因为它删除了数据库,该数据库包括所有存储过程,触发器等,而不仅仅是表。
爱好者2016年

2
我相信这个答案确实回答了发帖人想问的问题:“我如何轻松地从头开始使用我的sqlite数据库?” 如果可能的话,可能有人应该编辑问题以使其更清楚。
Akrikos

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);
}

4

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


3

一旦删除了所有表(表走后索引将消失),就我所知,SQLite数据库中什么也没有,尽管文件似乎没有收缩(通过快速测试,我刚刚做了) )。

因此,删除文件似乎是最快的-当您的应用尝试访问db文件时,应该重新创建该文件。


1
该文件不会缩小,因为那不是sqlite的工作方式-如果清理文件(基本上是从头开始重新创建),它只会将磁盘空间返回给操作系统。在此之前,文件已充满可重用空间。
paxdiablo,

嗯 因此,如果您没有文件删除/创建特权,或者有一些奇怪的多用户情况,则删除所有表并进行清理将很有意义。否则就删除东西?
Mike Woodhouse,2009年

3

使用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]))

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();
    }
}

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


0

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

echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
    sqlite3 -readonly "$db" | sqlite3 "$db"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.