Какая команда удаляет все таблицы в SQLite?
Точно так же я хотел бы удалить все индексы.
Ответы:
Я не думаю, что вы можете удалить все таблицы за один удар, но вы можете сделать следующее, чтобы получить команды:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
Результатом этого будет сценарий, который сбросит таблицы за вас. Для индексов просто замените 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')
.
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
для сброса последовательностей автоинкремента.
Используя 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]))
После того, как вы отбросили все таблицы (и индексы исчезнут, когда таблица переместится), то, насколько мне известно, в базе данных SQLite ничего не останется, хотя файл, похоже, не сжимается (из быстрого теста, который я только что сделал ).
Таким образом, удаление файла кажется самым быстрым - его нужно просто воссоздать, когда ваше приложение пытается получить доступ к файлу db.
У меня была эта проблема в Android, и я написал метод, похожий на it-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
Этот фрагмент кода перенаправляет вывод во временный файл, создает команды 'drop table', которые я хочу запустить (отправляя команды во временный файл), устанавливает стандартный вывод, затем выполняет команды из файла и, наконец, удаляет файл.
Или в приглашении оболочки, всего в две строки, без именованного временного файла, если $ db - это имя базы данных SQLite:
echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
sqlite3 -readonly "$db" | sqlite3 "$db"
Чтобы удалить также просмотры, добавьте ключевое слово 'view':
delete from sqlite_master where type in ('view', 'table', 'index', 'trigger');