SQLite에서 모든 테이블을 삭제하는 명령은 무엇입니까?
마찬가지로 모든 인덱스를 삭제하고 싶습니다.
답변:
한 번에 모든 테이블을 삭제할 수 있다고 생각하지 않지만 다음을 수행하여 명령을 얻을 수 있습니다.
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
이 결과는 테이블을 삭제하는 스크립트입니다. 인덱스의 경우 테이블을 인덱스로 바꾸십시오.
where
섹션 에서 다른 절을 사용하여 선택되는 테이블 또는 인덱스를 제한 할 수 있습니다 (예 : and name glob 'pax_*'
"pax_"로 시작하는 "").
이 스크립트의 생성을 간단한 bash (또는 cmd.exe) 스크립트에서 실행하는 것과 결합하여 실행할 명령이 하나뿐입니다.
당신이 걱정하지 않는 경우 어떤 아마 빠르다 - DB를의 정보, 당신이 단지는 하드 디스크 오프에 저장된 파일을 삭제할 수 있다고 생각합니다. 나는 이것을 테스트 한 적이 없지만 왜 작동하지 않는지 알 수 없습니다.
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'명령을 구성하고 (명령을 임시 파일로 전송) 출력을 다시 표준 출력으로 설정 한 다음 파일에서 명령을 실행합니다. 파일을 제거합니다.