모든 테이블 삭제 명령


86

SQLite에서 모든 테이블을 삭제하는 명령은 무엇입니까?

마찬가지로 모든 인덱스를 삭제하고 싶습니다.

답변:


86

한 번에 모든 테이블을 삭제할 수 있다고 생각하지 않지만 다음을 수행하여 명령을 얻을 수 있습니다.

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

이 결과는 테이블을 삭제하는 스크립트입니다. 인덱스의 경우 테이블을 인덱스로 바꾸십시오.

where섹션 에서 다른 절을 사용하여 선택되는 테이블 또는 인덱스를 제한 할 수 있습니다 (예 : and name glob 'pax_*'"pax_"로 시작하는 "").

이 스크립트의 생성을 간단한 bash (또는 cmd.exe) 스크립트에서 실행하는 것과 결합하여 실행할 명령이 하나뿐입니다.

당신이 걱정하지 않는 경우 어떤 아마 빠르다 - DB를의 정보, 당신이 단지는 하드 디스크 오프에 저장된 파일을 삭제할 수 있다고 생각합니다. 나는 이것을 테스트 한 적이 없지만 왜 작동하지 않는지 알 수 없습니다.


감사. 간단한 명령이 아니라이 엉뚱한 SQL 쿼리가 있다는 것이 매우 이상합니다.
alamodey

7
빈 sqlite 데이터베이스를 얻는 가장 쉬운 방법은 파일을 삭제 한 다음 연결하는 것입니다.
John Fouhy

2
따라서 내 마지막 단락 @JF.
paxdiablo

테이블에 연결된 트리거는 어떻게됩니까?
rds

@rds, 테이블을 삭제하면 테이블이 삭제되는 모든 트리거도 삭제됩니다. (테이블이 더 이상 존재하지 않기 때문에) 실행할 수 없을 때 트리거를 유지하는 것은 의미가 없습니다.
paxdiablo

83

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;

1
onUpgrade ()에서 실행하는 방법 ??
AZ_

간단하게 한 정도로 년대 DDL, 실행
노아

어떤 미친 이유로 다른 사람이이 질문을하는 경우, 위의 방법은 Titanium Mobile의 데이터베이스 API에서 모든 테이블을 삭제하는 데 효과적입니다.
Riley Dutton 2011

2
놀랍도록 영리합니다. 자체 개발 한 증분 업그레이드 시스템은 버전을 비교하는 스크립트 만 실행할 수 있습니다.이 트릭은 개선 할 필요가 없습니다. :)
Ivan G.

3
참고 :이 경우 데이터베이스 를 정리하려는 두 번째 시도 (적어도 최신 sqlite 사용)에서 이상한 "데이터베이스 파일 형식이 잘못되었습니다"문제가 발생할 수 있지만 delete from sqlite_master where type in ('table', 'index', 'trigger').
mlvljr

36
rm db/development.sqlite3

예, 이것은 데이터베이스를 삭제하지만 sqlite에는 테이블 외에 다른 것이있을 수 있습니다. 내용은 내 전체 답변을 참조하십시오
노아

9
데이터베이스에 여러 개의 연결이 열려 있으면 작동하지 않습니다. 이름 만 제거하는 * nix에서 연결은 핸들을 닫을 때까지 이름이 지정되지 않은 데이터베이스 파일로 계속 작업합니다. 스키마를 다시 작성하려는 경우 (모든 테이블 삭제, 새 테이블 만들기) 문제가 발생합니다.
jbarlow

3
테이블뿐만 아니라 모든 저장 프로 시저, 트리거 등을 포함하는 데이터베이스를 삭제 했으므로이 대답은 허용되지 않아야합니다.
Hobbyist

2
나는이 대답이 "내 sqlite 데이터베이스로 처음부터 쉽게 다시 시작하는 방법은 무엇입니까?"라는 포스터의 질문에 대한 답이라고 생각합니다. 누군가 가능하다면 질문을 더 명확하게 편집해야합니다.
Akrikos

22

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

테이블 삭제 및 파일 삭제와 관련된 다른 답변에 추가하고 싶습니다 delete from sqlite_sequence. 자동 증가 시퀀스를 재설정 하기 위해 실행할 수도 있습니다 .


4

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]))

3

모든 테이블을 삭제하면 (테이블이 이동하면 인덱스가 사라집니다) 파일이 축소되지는 않지만 SQLite 데이터베이스에 아무것도 남아 있지 않습니다 (빠른 테스트에서 방금 수행 한 ).

따라서 파일을 삭제하는 것이 가장 빠른 것 같습니다. 앱이 db 파일에 액세스하려고 할 때 다시 만들어야합니다.


1
sqlite가 작동하는 방식이 아니기 때문에 파일이 축소되지 않습니다. 파일을 진공 처리하는 경우 (기본적으로 처음부터 다시 생성) OS에 디스크 공간 만 반환합니다. 그때까지 파일은 재사용 가능한 공간으로 가득 차 있습니다.
paxdiablo

야아. 따라서 파일 삭제 / 만들기 권한이 없거나 이상한 다중 사용자 상황이있는 경우 모든 테이블을 삭제하고 정리하는 것이 좋습니다. 그렇지 않으면 그냥 삭제 하시겠습니까?
Mike Woodhouse

2

나는 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();
    }
}

1

이것이 가장 방탄 또는 휴대용 솔루션이라고 말할 수는 없지만 테스트 스크립트에서는 작동합니다.

.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'명령을 구성하고 (명령을 임시 파일로 전송) 출력을 다시 표준 출력으로 설정 한 다음 파일에서 명령을 실행합니다. 파일을 제거합니다.


0

또는 쉘 프롬프트에서 이름이 지정된 임시 파일없이 단 두 줄로 $ db가 SQLite 데이터베이스 이름이라고 가정합니다.

echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
    sqlite3 -readonly "$db" | sqlite3 "$db"

0

보기도 삭제하려면 'view'키워드를 추가하십시오.

delete from sqlite_master where type in ('view', 'table', 'index', 'trigger');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.