Antworten:
Ich glaube nicht, dass Sie alle Tabellen mit einem Schlag löschen können, aber Sie können Folgendes tun, um die Befehle zu erhalten:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
Die Ausgabe davon ist ein Skript, das die Tabellen für Sie löscht. Ersetzen Sie für Indizes einfach die Tabelle durch den Index.
Sie können andere Klauseln in diesem where
Abschnitt verwenden, um die Auswahl der ausgewählten Tabellen oder Indizes and name glob 'pax_*'
einzuschränken (z. B. " " für diejenigen, die mit "pax_" beginnen).
Sie können die Erstellung dieses Skripts mit der Ausführung in einem einfachen Bash-Skript (oder cmd.exe-Skript) kombinieren, sodass nur ein Befehl ausgeführt werden muss.
Wenn Sie nicht über kümmern sich jede der Informationen in der DB, ich denke , man kann einfach die Datei löschen , es in von der Festplatte gespeichert ist - die wahrscheinlich schneller ist. Ich habe das noch nie getestet, aber ich kann nicht verstehen, warum es nicht funktionieren würde.
Obwohl es keinen Befehl DROP ALL TABLES gibt, können Sie die folgenden Befehle verwenden.
Hinweis: Diese Befehle können Ihre Datenbank möglicherweise beschädigen. Stellen Sie daher sicher, dass Sie über ein Backup verfügen
PRAGMA writable_schema = 1;
delete from sqlite_master where type in ('table', 'index', 'trigger');
PRAGMA writable_schema = 0;
Sie möchten dann den gelöschten Speicherplatz mit wiederherstellen
VACUUM;
und ein guter Test, um sicherzustellen, dass alles in Ordnung ist
PRAGMA INTEGRITY_CHECK;
delete from sqlite_master where type in ('table', 'index', 'trigger')
.
rm db/development.sqlite3
Ich hatte das gleiche Problem mit SQLite und Android. Hier ist meine Lösung:
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);
}
Ich möchte zu anderen Antworten hinzufügen, bei denen Tabellen gelöscht und die Datei nicht gelöscht werden, die Sie auch ausführen können delete from sqlite_sequence
, um automatische Inkrementierungssequenzen zurückzusetzen.
Verwendung von 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]))
Sobald Sie alle Tabellen gelöscht haben (und die Indizes verschwinden, wenn die Tabelle gelöscht wird), ist meines Wissens nichts mehr in einer SQLite-Datenbank vorhanden, obwohl die Datei nicht zu schrumpfen scheint (nach einem kurzen Test, den ich gerade durchgeführt habe) ).
Das Löschen der Datei scheint also am schnellsten zu sein - sie sollte nur neu erstellt werden, wenn Ihre App versucht, auf die Datenbankdatei zuzugreifen.
Ich hatte dieses Problem in Android und habe eine ähnliche Methode wie it-west geschrieben.
Da ich AUTOINCREMENT
in meinen Tabellen Primärschlüssel verwendet habe, wurde eine Tabelle aufgerufen sqlite_sequence
. SQLite stürzte ab, wenn die Routine versuchte, diese Tabelle zu löschen. Ich konnte die Ausnahme auch nicht fangen. Unter https://www.sqlite.org/fileformat.html#internal_schema_objects habe ich festgestellt, dass es mehrere dieser internen Schematabellen geben kann , die ich nicht löschen wollte. Die Dokumentation besagt, dass jede dieser Tabellen Namen hat, die mit sqlite_ beginnen, also habe ich diese Methode geschrieben
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();
}
}
Ich kann nicht sagen, dass dies die kugelsicherste oder tragbarste Lösung ist, aber sie funktioniert für meine Testskripte:
.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
Dieses Codebit leitet die Ausgabe in eine temporäre Datei um, erstellt die 'drop table'-Befehle, die ich ausführen möchte (Senden der Befehle an die temporäre Datei), setzt die Ausgabe wieder auf Standard out, führt dann die Befehle aus der Datei aus und schließlich entfernt die Datei.