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