SQLiteのすべてのテーブルを削除するコマンドは何ですか?
同様に、すべてのインデックスを削除したいと思います。
rm db/development.sqlite3
1回のヒットですべてのテーブルを削除できるとは思いませんが、次のようにしてコマンドを取得できます。
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
この出力は、テーブルをドロップするスクリプトです。インデックスの場合、テーブルをインデックスに置き換えるだけです。
where
セクションで他の句を使用して、選択するテーブルまたはインデックスを制限できます(「and name glob 'pax_*'
」は「pax_」で始まるものです)。
このスクリプトの作成と単純なbash(またはcmd.exe)スクリプトでの実行を組み合わせて、実行するコマンドが1つだけになるようにすることができます。
DB内の情報のanyを気にしない場合は、ハードディスクに保存されているファイルを削除するだけでよいと思います-これはおそらくより高速です。これをテストしたことはありませんが、なぜ機能しないのかわかりません。
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;
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
は、自動インクリメントシーケンスをリセットします。
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]))
この問題は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();
}
}
すべてのテーブルを削除すると(そしてテーブルが進むとインデックスが消えます)、SQLiteデータベースには、ファイルが縮小していないように見えますが、SQLiteデータベースには何も残っていません(簡単なテストから)。
そのため、ファイルの削除は最速のように思われます。アプリがdbファイルにアクセスしようとしたときに、ファイルを再作成する必要があります。
これが最も防弾またはポータブルなソリューションであるとは言えませんが、テストスクリプトでは機能します。
.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
このコードは、出力を一時ファイルにリダイレクトし、実行する「ドロップテーブル」コマンドを構築し(コマンドを一時ファイルに送信)、出力を標準出力に戻し、ファイルからコマンドを実行し、最後にファイルを削除します。