Jakie jest polecenie usunięcia wszystkich tabel w SQLite?
Podobnie chciałbym usunąć wszystkie indeksy.
Odpowiedzi:
Nie sądzę, abyś mógł upuścić wszystkie tabele jednym uderzeniem, ale możesz wykonać następujące czynności, aby uzyskać polecenia:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
Wynikiem tego jest skrypt, który usunie tabele za Ciebie. W przypadku indeksów wystarczy zastąpić tabelę indeksem.
Możesz użyć innych klauzul w where
sekcji, aby ograniczyć wybrane tabele lub indeksy (np. „ and name glob 'pax_*'
” Dla tych zaczynających się od „pax_”).
Możesz połączyć utworzenie tego skryptu z uruchomieniem go w prostym skrypcie bash (lub cmd.exe), więc jest tylko jedno polecenie do uruchomienia.
Jeśli nie dbasz o żadne informacje w bazie danych, myślę, że możesz po prostu usunąć plik, w którym jest przechowywany, z dysku twardego - to prawdopodobnie szybciej. Nigdy tego nie testowałem, ale nie rozumiem, dlaczego to nie zadziała.
Chociaż prawdą jest, że nie ma polecenia DROP ALL TABLES, możesz użyć następującego zestawu poleceń.
Uwaga: te polecenia mogą potencjalnie uszkodzić bazę danych, więc upewnij się, że masz kopię zapasową
PRAGMA writable_schema = 1;
delete from sqlite_master where type in ('table', 'index', 'trigger');
PRAGMA writable_schema = 0;
następnie chcesz odzyskać usunięte miejsce za pomocą
VACUUM;
i dobry test, aby upewnić się, że wszystko jest w porządku
PRAGMA INTEGRITY_CHECK;
delete from sqlite_master where type in ('table', 'index', 'trigger')
.
rm db/development.sqlite3
Miałem ten sam problem z SQLite i Androidem. Oto moje rozwiązanie:
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);
}
Chciałbym dodać do innych odpowiedzi dotyczących usuwania tabel i nie usuwania pliku, które można również wykonać, delete from sqlite_sequence
aby zresetować sekwencje autoinkrementacji.
Korzystanie z 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]))
Po upuszczeniu wszystkich tabel (a indeksy znikną, gdy tabela zostanie przeniesiona), o ile wiem, w bazie danych SQLite nie ma nic, chociaż plik nie wydaje się zmniejszać (z szybkiego testu, który właśnie zrobiłem ).
Dlatego usunięcie pliku wydaje się być najszybsze - należy go odtworzyć, gdy aplikacja próbuje uzyskać dostęp do pliku db.
Miałem ten problem w Androidzie i napisałem metodę podobną do it-west.
Ponieważ użyłem AUTOINCREMENT
kluczy podstawowych w moich tabelach, powstała tabela o nazwie sqlite_sequence
. SQLite ulegał awarii, gdy procedura próbowała usunąć tę tabelę. Nie mogłem też złapać wyjątku. Patrząc na https://www.sqlite.org/fileformat.html#internal_schema_objects , dowiedziałem się, że może istnieć kilka takich wewnętrznych tabel schematów , których nie chciałbym usuwać. Dokumentacja mówi, że każda z tych tabel ma nazwy zaczynające się od sqlite_, więc napisałem tę metodę
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();
}
}
Nie mogę powiedzieć, że jest to najbardziej kuloodporne lub przenośne rozwiązanie, ale działa w przypadku moich skryptów testowych:
.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
Ten fragment kodu przekierowuje dane wyjściowe do pliku tymczasowego, konstruuje polecenia „drop table”, które chcę uruchomić (wysyłanie poleceń do pliku tymczasowego), ustawia wyjście z powrotem na standardowe wyjście, następnie wykonuje polecenia z pliku i na koniec usuwa plik.
Aby usunąć również widoki, dodaj słowo kluczowe „widok”:
delete from sqlite_master where type in ('view', 'table', 'index', 'trigger');