Lệnh bỏ tất cả các bảng trong SQLite là gì?
Tương tự, tôi muốn bỏ tất cả các chỉ mục.
Câu trả lời:
Tôi không nghĩ rằng bạn có thể bỏ tất cả các bảng trong một lần đánh nhưng bạn có thể làm như sau để nhận các lệnh:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
Đầu ra của điều này là một tập lệnh sẽ thả các bảng cho bạn. Đối với các chỉ mục, chỉ cần thay thế bảng bằng chỉ mục.
Bạn có thể sử dụng các mệnh đề khác trong where
phần để giới hạn bảng hoặc chỉ mục nào được chọn (chẳng hạn như " and name glob 'pax_*'
" cho những bảng bắt đầu bằng "pax_").
Bạn có thể kết hợp việc tạo tập lệnh này với việc chạy nó trong một tập lệnh bash (hoặc cmd.exe) đơn giản để chỉ có một lệnh để chạy.
Nếu bạn không quan tâm đến bất kỳ thông tin nào trong DB, tôi nghĩ bạn có thể xóa tệp được lưu trữ trong đĩa cứng - điều đó có thể nhanh hơn. Tôi chưa bao giờ thử nghiệm điều này nhưng tôi không thể hiểu tại sao nó không hoạt động.
Mặc dù đúng là không có lệnh DROP ALL TABLES, nhưng bạn có thể sử dụng nhóm lệnh sau.
Lưu ý: Các lệnh này có khả năng làm hỏng cơ sở dữ liệu của bạn, vì vậy hãy đảm bảo bạn có bản sao lưu
PRAGMA writable_schema = 1;
delete from sqlite_master where type in ('table', 'index', 'trigger');
PRAGMA writable_schema = 0;
sau đó bạn muốn khôi phục không gian đã xóa với
VACUUM;
và một bài kiểm tra tốt để đảm bảo mọi thứ đều ổn
PRAGMA INTEGRITY_CHECK;
delete from sqlite_master where type in ('table', 'index', 'trigger')
.
rm db/development.sqlite3
Tôi đã gặp vấn đề tương tự với SQLite và Android. Đây là Giải pháp của tôi:
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);
}
Tôi muốn thêm vào các câu trả lời khác liên quan đến việc giảm bảng và không xóa tệp, mà bạn cũng có thể thực hiện delete from sqlite_sequence
để đặt lại trình tự tăng tự động.
Khi bạn đã bỏ tất cả các bảng (và các chỉ mục sẽ biến mất khi hết bảng) thì không còn gì trong cơ sở dữ liệu SQLite theo như tôi biết, mặc dù tệp dường như không bị thu nhỏ (từ một thử nghiệm nhanh mà tôi vừa làm ).
Vì vậy, việc xóa tệp sẽ có vẻ là nhanh nhất - nó chỉ nên được tạo lại khi ứng dụng của bạn cố gắng truy cập tệp db.
Sử dụng 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]))
Tôi đã gặp sự cố này trong Android và tôi đã viết một phương pháp tương tự như it-west.
Vì tôi đã sử dụng AUTOINCREMENT
các khóa chính trong các bảng của mình, nên có một bảng được gọi sqlite_sequence
. SQLite sẽ gặp sự cố khi quy trình cố gắng loại bỏ bảng đó. Tôi cũng không thể bắt được ngoại lệ. Nhìn vào https://www.sqlite.org/fileformat.html#internal_schema_objects , tôi biết rằng có thể có một số bảng lược đồ nội bộ này mà tôi không muốn bỏ. Tài liệu nói rằng bất kỳ bảng nào trong số này có tên bắt đầu bằng sqlite_ vì vậy tôi đã viết phương pháp này
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();
}
}
Tôi không thể nói đây là giải pháp chống đạn hay di động nhất, nhưng nó phù hợp với các tập lệnh thử nghiệm của tôi:
.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
Đoạn mã này chuyển hướng đầu ra đến một tệp tạm thời, xây dựng các lệnh 'bảng thả' mà tôi muốn chạy (gửi các lệnh tới tệp tạm thời), đặt đầu ra trở lại chuẩn, sau đó thực hiện các lệnh từ tệp, và cuối cùng loại bỏ tệp.