Яка команда видалити всі таблиці в 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')
.
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
для скидання послідовностей автоматичного збільшення.
Як тільки ви скинете всі таблиці (і індекси зникнуть, коли таблиця перейде), тоді, наскільки мені відомо, у базі даних SQLite нічого не залишилось, хоча файл, здається, не зменшується (із швидкого тесту, який я щойно зробив) ).
Тож видалення файлу здається найшвидшим - його слід просто відтворити, коли ваша програма намагається отримати доступ до файлу db.
Використання 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]))
У мене виникла ця проблема в 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
Цей біт коду перенаправляє вихідні дані у тимчасовий файл, створює команди "падіння таблиці", які я хочу запустити (надсилання команд у тимчасовий файл), повертає вихід на стандартний вихід, потім виконує команди з файлу і, нарешті, видаляє файл.