Что такое команда, чтобы удалить все таблицы в SQLite?
Точно так же я хотел бы удалить все индексы.
Что такое команда, чтобы удалить все таблицы в SQLite?
Точно так же я хотел бы удалить все индексы.
Я не думаю, что вы можете удалить все таблицы одним ударом, но вы можете сделать следующее, чтобы получить команды:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
Результатом этого является скрипт, который удалит для вас таблицы. Для индексов просто замените таблицу на index.
Вы можете использовать другие предложения в разделе where
, чтобы ограничить выбор таблиц или индексов (например, "and name glob 'pax_*'
" для тех, которые начинаются с "pax_").
Вы можете совместить создание этого сценария с его запуском в простом сценарии bash (или cmd.exe), чтобы выполнить только одну команду.
Если вам не нужна какая-либо информация в БД, я думаю, вы можете просто удалить файл, в котором она хранится, с жесткого диска - это, вероятно, быстрее. Я никогда не проверял это, но я не понимаю, почему это не сработает.
Хотя это правда, что нет команды 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')
.
- person mlvljr; 19.10.2012
android_metadata
. В следующий раз, когда база данных будет открыта, эта таблица будет воссоздана, но чтобы воссоздать ее немедленно, вы можете изменить ведение журнала упреждающей записи или ограничения внешнего ключа на противоположное тому, как вы его настроили, а затем вернуть обратно. Это вызовет внутренний вызов reconfigure()
, который запишет таблицу android_metadata
.
- person tophyr; 30.07.2015
type
также может быть триггером. Наверное, их тоже стоит удалить, я думаю. Но если вы удаляете все возможные типы в sqlite_master
, вы можете просто delete
без ограничения type
.
- person spaaarky21; 08.06.2016
У меня была такая же проблема с 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);
}
Используя писклит:
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]))
Я хотел бы добавить к другим ответам, связанным с удалением таблиц и без удаления файла, что вы также можете выполнить delete from sqlite_sequence
для сброса последовательностей автоинкремента.
Как только вы удалили все таблицы (и индексы исчезнут, когда таблица исчезнет), в базе данных SQLite, насколько я знаю, ничего не останется, хотя файл, похоже, не сжимается (из быстрого теста, который я только что сделал ).
Таким образом, удаление файла кажется самым быстрым - его нужно просто воссоздать, когда ваше приложение попытается получить доступ к файлу db.
У меня была эта проблема в Android, и я написал метод, аналогичный этому - 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();
}
}
Не могу сказать, что это самое пуленепробиваемое или портативное решение, но для моих тестовых скриптов оно работает:
.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
Этот фрагмент кода перенаправляет вывод во временный файл, создает команды «удалить таблицу», которые я хочу запустить (отправляя команды во временный файл), устанавливает вывод обратно в стандартный вывод, затем выполняет команды из файла и, наконец, удаляет файл.
Или в приглашении оболочки, всего в две строки, без именованного временного файла, предполагая, что $db — это имя базы данных SQLite:
echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
sqlite3 -readonly "$db" | sqlite3 "$db"
Чтобы удалить также просмотры, добавьте ключевое слово «просмотр»:
delete from sqlite_master where type in ('view', 'table', 'index', 'trigger');