web-dev-qa-db-ja.com

すべてのテーブルを削除するコマンド

SQLiteのすべてのテーブルを削除するコマンドは何ですか?

同様に、すべてのインデックスを削除したいと思います。

78
alamodey
rm db/development.sqlite3
33
alamodey

1回のヒットですべてのテーブルを削除できるとは思いませんが、次のようにしてコマンドを取得できます。

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

この出力は、テーブルをドロップするスクリプトです。インデックスの場合、テーブルをインデックスに置き換えるだけです。

whereセクションで他の句を使用して、選択するテーブルまたはインデックスを制限できます(「and name glob 'pax_*'」は「pax_」で始まるものです)。

このスクリプトの作成と単純なbash(またはcmd.exe)スクリプトでの実行を組み合わせて、実行するコマンドが1つだけになるようにすることができます。

DB内の情報のanyを気にしない場合は、ハードディスクに保存されているファイルを削除するだけでよいと思います-これはおそらくより高速です。これをテストしたことはありませんが、なぜ機能しないのかわかりません。

75
paxdiablo

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;
74
Noah

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);
}
22
it-west.net

テーブルを削除することとファイルを削除しないことを含む他の回答に追加したいのですが、delete from sqlite_sequenceは、自動インクリメントシーケンスをリセットします。

4
Flavio Tordini

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]))
3
user3467349

この問題は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();
    }
}
2
Jon

すべてのテーブルを削除すると(そしてテーブルが進むとインデックスが消えます)、SQLiteデータベースには、ファイルが縮小していないように見えますが、SQLiteデータベースには何も残っていません(簡単なテストから)。

そのため、ファイルの削除は最速のように思われます。アプリがdbファイルにアクセスしようとしたときに、ファイルを再作成する必要があります。

2
Mike Woodhouse

これが最も防弾またはポータブルなソリューションであるとは言えませんが、テストスクリプトでは機能します。

.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

このコードは、出力を一時ファイルにリダイレクトし、実行する「ドロップテーブル」コマンドを構築し(コマンドを一時ファイルに送信)、出力を標準出力に戻し、ファイルからコマンドを実行し、最後にファイルを削除します。

0
Matt Malone