2009-02-08 21 views

Respuesta

27
rm db/development.sqlite3 
+0

sí, esto elimina la base de datos, pero puede haber otra cosa en sqlite además de las tablas; Vea mi respuesta completa para más detalles – Noah

+7

Si la base de datos tiene múltiples conexiones abiertas, esto no funcionará. En un * nix solo eliminará el nombre, y las conexiones continuarán trabajando con el archivo de base de datos sin nombre hasta que cierren sus identificadores. Si la intención es reescribir el esquema (descartar todas las tablas, crear nuevas tablas), entonces tendrá problemas. – jbarlow

+2

Esta no debería ser la respuesta aceptada, ya que eliminó la base de datos, que incluye todos los procedimientos almacenados, disparadores, etc., no solo las tablas. – Hobbyist

72

no creo que se puede eliminar todas las tablas de un solo golpe, pero se puede hacer lo siguiente para obtener los comandos:

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

La salida de este es un script que elimine las tablas para usted. Para los índices, simplemente reemplace la tabla con el índice.

Puede usar otras cláusulas en la sección where para limitar qué tablas o índices se seleccionan (como "and name glob 'pax_*'" para aquellos que comienzan con "pax_").

Puede combinar la creación de este script con su ejecución en un script simple bash (o cmd.exe) por lo que solo hay que ejecutar un comando.

Si no se preocupan por cualquier de la información en la base de datos, creo que sólo se puede eliminar el archivo se almacena en el disco duro fuera - que es probablemente más rápido. Nunca lo he probado, pero no veo por qué no funcionaría.

+0

Gracias. Es muy extraño que no haya un comando simple sino una consulta SQL hacky. – alamodey

+5

Bueno, la forma más fácil de obtener una base de datos vacía de sqlite es simplemente eliminar el archivo y luego conectarse a él ... –

+2

De ahí mi último párrafo, @JF. – paxdiablo

2

Una vez que haya eliminado todas las tablas (y los índices desaparecerán cuando la tabla vaya), no hay nada en una base de datos SQLite hasta donde yo sé, aunque el archivo no parece contraerse (de una rápida prueba que acabo de hacer).

Por lo tanto, eliminar el archivo parecería ser el más rápido: solo debería recrearse cuando su aplicación intente acceder al archivo db.

+1

El archivo no se contrae porque esa no es la forma en que funciona sqlite; solo devolverá espacio en disco al sistema operativo si vacía el archivo (básicamente, recíclelo desde cero). Hasta entonces, el archivo está lleno de espacio reutilizable. – paxdiablo

+0

Yah. Por lo tanto, descartar todas las tablas y pasar la aspiradora tendría sentido si no tiene privilegios para eliminar/crear archivos, o si existe una extraña situación multiusuario. De lo contrario, simplemente elimine la cosa? –

63

Si bien es cierto que no hay ningún comando DROP ALL TABLES, puede usar el siguiente conjunto de comandos.

Nota: Estos comandos tienen el potencial para corromper su base de datos, por lo que asegúrese de que tiene una copia de seguridad

PRAGMA writable_schema = 1; 
delete from sqlite_master where type in ('table', 'index', 'trigger'); 
PRAGMA writable_schema = 0; 

a continuación, desea recuperar el espacio que ha de suprimirse

VACUUM; 

y una buena prueba para asegurarse de que todo está bien

PRAGMA INTEGRITY_CHECK; 
+1

cómo ejecutarlos en onUpgrade() ?? –

+0

Simplemente ejecute el DDL, eso es suficiente – Noah

+0

En caso de que alguien más tenga esta pregunta, lo anterior funciona para eliminar todas las tablas en la API de base de datos de Titanium Mobile. –

4

Me gustaría agregar a otras respuestas que implican la eliminación de tablas y no eliminar el archivo, que también puede ejecutar delete from sqlite_sequence para restablecer las secuencias de incremento automático.

21

Tuve el mismo problema con SQLite y Android. Aquí está mi solución:

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); 
} 
2

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

tuve este problema en el androide y escribí un método similar al que-oeste.

Porque utilicé las claves primarias AUTOINCREMENT en mis tablas, había una tabla llamada sqlite_sequence. SQLite se bloqueaba cuando la rutina intentaba abandonar esa tabla. Tampoco pude ver la excepción.En cuanto a https://www.sqlite.org/fileformat.html#internal_schema_objects, me enteré de que podría haber varias de estas tablas de esquema interno que no deseaba soltar. La documentación dice que cualquiera de estas tablas tienen nombres que comienzan con sqlite_ así que escribí este método

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

No puedo decir que esta es la solución más a prueba de balas o portátiles, pero funciona para mis scripts de pruebas:

.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 

Este trozo de código redirige la salida a un archivo temporal, construye el 'drop table' comandos que desee ejecutar (el envío de los comandos para el archivo temporal), establece la salida de nuevo a la salida estándar, a continuación, ejecuta los comandos del archivo, y finalmente elimina el archivo.

Cuestiones relacionadas