Jakie jest polecenie usunięcia wszystkich tabel w SQLite?
Podobnie chciałbym usunąć wszystkie indeksy.
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ą
i dobry test, aby upewnić się, że wszystko jest w porządku
PRAGMA INTEGRITY_CHECK;
źródło
delete from sqlite_master where type in ('table', 'index', 'trigger')
.źródło
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); }
źródło
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.źródło
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]))
źródło
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.
źródło
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 nazwiesqlite_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(); } }
źródło
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.
źródło
Lub w wierszu polecenia powłoki, w zaledwie dwóch wierszach, bez nazwanego pliku tymczasowego, zakładając, że $ db to nazwa bazy danych SQLite:
echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" | sqlite3 -readonly "$db" | sqlite3 "$db"
źródło
Aby usunąć również widoki, dodaj słowo kluczowe „widok”:
delete from sqlite_master where type in ('view', 'table', 'index', 'trigger');
źródło