Команда удаления всех таблиц - PullRequest
76 голосов
/ 08 февраля 2009

Какая команда удаляет все таблицы в SQLite?

Точно так же я хотел бы отбросить все индексы.

Ответы [ 9 ]

75 голосов
/ 08 февраля 2009

Я не думаю, что вы можете отбросить все таблицы одним ударом, но вы можете сделать следующее, чтобы получить команды:

select 'drop table ' || name || ';' from sqlite_master
    where type = 'table';

Результатом этого является скрипт, который отбрасывает таблицы для вас. Для индексов просто замените таблицу на индекс.

Вы можете использовать другие предложения в разделе where, чтобы ограничить выбор таблиц или индексов (например, "and name glob 'pax_*'" для тех, которые начинаются с "pax _").

Вы можете объединить создание этого сценария с его выполнением в простом сценарии bash (или cmd.exe), чтобы можно было запустить только одну команду.

Если вас не волнует любая информация в БД, я думаю, что вы можете просто удалить файл, хранящийся на жестком диске, - это, вероятно, быстрее. Я никогда не проверял это, но я не понимаю, почему это не сработает.

73 голосов
/ 14 февраля 2009

Хотя команда 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;
33 голосов
/ 09 февраля 2009
rm db/development.sqlite3
22 голосов
/ 27 апреля 2013

У меня была такая же проблема с 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);
}
4 голосов
/ 09 февраля 2012

Я хотел бы добавить к другим ответам, связанным с удалением таблиц и без удаления файла, что вы также можете выполнить delete from sqlite_sequence для сброса последовательностей автоинкремента.

3 голосов
/ 16 ноября 2014

Использование 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]))
2 голосов
/ 31 августа 2017

У меня была эта проблема в Android, и я написал метод, аналогичный этому - запад.

Поскольку я использовал 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();
    }
}
2 голосов
/ 08 февраля 2009

После того, как вы удалили все таблицы (и индексы исчезнут, когда таблица выйдет), то, насколько я знаю, в базе данных SQLite ничего не останется, хотя файл, похоже, не сжимается (из быстрого теста Я только что сделал).

Таким образом, удаление файла может показаться самым быстрым - его нужно просто воссоздать, когда ваше приложение попытается получить доступ к файлу БД.

0 голосов
/ 18 января 2018

Не могу сказать, что это самое пуленепробиваемое или портативное решение, но оно работает для моих сценариев тестирования:

.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

Этот бит кода перенаправляет вывод во временный файл, создает команды «перетаскивания таблицы», которые я хочу выполнить (отправка команд во временный файл), возвращает вывод в стандартный вывод, затем выполняет команды из файла и, наконец, удаляет файл.

...