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


83

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

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

回答:


82

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

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

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

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

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

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


ありがとう。単純なコマンドではなく、このハッキーなSQLクエリがあるのは非常に奇妙です。
alamodey 2009

7
まあ、空のSQLiteデータベースは単にファイルを削除することで取得し、それに接続するための最も簡単な方法...
ジョンFouhy

2
したがって、私の最後の段落、@ JF。
paxdiablo 2009

テーブルにアタッチされたトリガーはどうなりますか?
rds 2015

@rds、テーブルをドロップすると、そのテーブルのすべてのトリガーも削除されます。(テーブルが存在しなくなったため)トリガーが起動できない場合にトリガーを保持することはほとんど意味がありません。
paxdiablo 2015

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_ 2011

DDLを実行するだけで十分です
ノア

なんらかの奇妙な理由で他の誰かがこの質問をした場合、上記はTitaniumMobileのデータベースAPIのすべてのテーブルを削除するために機能します。
ライリーダットン2011

2
信じられないほど賢い。私たちの自家製インクリメンタルアップグレードシステムは、バージョンを比較するスクリプトのみを実行できます。このトリックには、改善は必要ありません:)
Ivan G.

3
注:これにより、データベースを2回目にクリーンアップしようとすると(少なくとも最新のsqliteでは)奇妙な「データベースファイルの形式が正しくない」問題が発生する可能性がありますが、のようなものを使用すると問題なく動作するようdelete from sqlite_master where type in ('table', 'index', 'trigger')です。
mlvljr 2012年

35
rm db/development.sqlite3

はい、これはデータベースを削除しますが、sqliteにはテーブル以外のものがある可能性があります。詳細については、私の完全な回答を参照してください
ノア

9
データベースで複数の接続が開いている場合、これは機能しません。名前を削除するだけの* nixでは、接続は、ハンドルを閉じるまで、名前のないデータベースファイルで作業を続けます。スキーマを書き直す(すべてのテーブルを削除し、新しいテーブルを作成する)ことを目的としている場合は、問題が発生します。
jbarlow

3
これは、テーブルだけでなく、すべてのストアドプロシージャ、トリガーなどを含むデータベースを削除したため、受け入れられる答えではありません。
愛好家2016年

2
この答えは、ポスターが尋ねるつもりだった質問に答えると思います。「sqliteデータベースを最初から簡単にやり直すにはどうすればよいですか?」誰かがおそらく質問をより明確にするために編集する必要があります...それが可能であれば。
Akrikos 2017

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の動作方法ではないため、ファイルは縮小されません。ファイルをバキュームした場合にのみ、ディスク領域がOSに返されます(基本的には最初から再作成します)。それまでは、ファイルは再利用可能なスペースでいっぱいです。
paxdiablo 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でこの問題を抱えていて、それに似た方法を書きました-西。

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

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


0

または、シェルプロンプトで、名前付きの一時ファイルなしで2行で、$ dbがSQLiteデータベース名であると想定します。

echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
    sqlite3 -readonly "$db" | sqlite3 "$db"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.