2009-10-21 63 views
719

¿Cómo puedo, confiablemente, verificar en SQLite, si existe una tabla de usuario particular?¿Cómo verifico en SQLite si existe una tabla?

No estoy preguntando por formas poco confiables como comprobar si un "select *" en la tabla devolvió un error o no (¿es incluso una buena idea?).

La razón es la siguiente:

En mi programa, tengo que crear y luego rellenar algunas tablas si no existen ya.

Si ya existen, necesito actualizar algunas tablas.

¿Debo tomar alguna otra ruta en lugar de señalar que las tablas en cuestión ya han sido creadas, por ejemplo, creando/poniendo/configurando un determinado indicador en el archivo de configuración/inicialización de mi programa en el disco o algo así?

¿O mi enfoque tiene sentido?

+0

SQLite lanzará una excepción si la tabla en una selección no existe. Simplemente no hay necesidad de ningún trabajo más sofisticado. – NoChance

+8

@NoChance lo hará, pero también lo hará cualquier cantidad de otras cosas. Eso es un poco como ver si ese árbol está realmente ahí conduciendo hacia adelante con los ojos cerrados, lo descubrirás de una forma u otra :) – randomsock

+0

@randomsock, buen ejemplo, pero un poco aterrador, especialmente si el auto fuera mi auto ... – NoChance

Respuesta

821

me perdí la FAQ.

De todos modos, para futuras consultas, la consulta completa es:

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name'; 
+6

¿Cuál de la documentación de SQLite cubre estas tablas del sistema? –

+28

@Pawel Veselov: La sección titulada "Formato de archivo para SQLite bases de datos": http://www.sqlite.org/fileformat2.html –

+1

Esto no funciona si está utilizando Adobe Air SQLite, aquí hay una (mejor) alternativo para el caso de que se está programando en AS3/Aire: http://stackoverflow.com/questions/4601707/air-and-sqlite-if-table-exists-conditional – CenterOrbit

23

Ver this:

SELECT name FROM sqlite_master 
WHERE type='table' 
ORDER BY name; 
35

usted podría intentar:

SELECT name FROM sqlite_master WHERE name='table_name' 
+3

type = mesa sería útil aunque – mafu

+0

Si usando C#, no utilice este comando en un lector de 'SQLiteReader = cmd.ExecuteReader();' 'y hacer un dt.Load (lector)' (donde 'dt 'es un' DataTable'). Encontré que da esta excepción 'Object reference is not an instance of object' on the' .Load() 'si no se encuentra la tabla. En su lugar, use un adaptador 'SQLiteDataAdapter = new SQLiteDataAdapter (cmd); 'y hacer' adapter.Fill (ds) ', donde' ds' es un 'DataSet'. A continuación, puede ver si 'ds.Tables.Count> 0' y' devuelve ds.Tables [0]; 'si es así (o' else return null'). A continuación, puede comprobar que '' DataTable' por ser null', si 'dt.Rows! = Null', y si' dt.Rows.Count> 0' – vapcguy

467

Si está utilizando la versión de SQLite 3.3+ puede crear fácilmente una mesa con:

create table if not exists TableName (col1 typ1, ..., colN typN) 

De la misma manera , puede eliminar una tabla solo si existe utilizando:

drop table if exists TableName 
+3

Tenga en cuenta que la instrucción 'create table' está incompleta (falta la especificación de columnas de la tabla). –

+9

también hay construcción similar para los índices: ** crear índice si no existe TableName_col1 en NombreTabla (col1) ** – lowtech

+13

Esto no debería ser la respuesta aceptada, pero que si la pregunta se redacta de otra. El OP no preguntó cómo verificar una tabla antes de descartarla o crearla. ¿Qué sucede si tiene que consultar una tabla que posiblemente no exista? Este es el problema que estoy enfrentando ahora, y la respuesta aceptada funciona mejor en esta declaración general del problema. Esta es una buena alternativa rápida. – Dagrooms

12

El siguiente código devuelve 1 si la tabla existe o 0 si la tabla no existe.

SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table" 
145

Una variación sería utilizar SELECT COUNT (*) en lugar de SELECT NAME, es decir

SELECT count(*) FROM sqlite_master WHERE type='table' AND name='table_name'; 

Esto devolverá 0, si la tabla no existe, 1 si lo hace. Esto probablemente sea útil en su programación ya que un resultado numérico es más rápido/más fácil de procesar. A continuación se muestra cómo harías esto en Android usando SQLiteDatabase, Cursor, rawQuery con parámetros.

boolean tableExists(SQLiteDatabase db, String tableName) 
{ 
    if (tableName == null || db == null || !db.isOpen()) 
    { 
     return false; 
    } 
    Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM sqlite_master WHERE type = ? AND name = ?", new String[] {"table", tableName}); 
    if (!cursor.moveToFirst()) 
    { 
     cursor.close(); 
     return false; 
    } 
    int count = cursor.getInt(0); 
    cursor.close(); 
    return count > 0; 
} 
+25

Creo que un "SELECT 1" sería aún más rápido. – PatchyFog

+0

¿Por qué cursor.getInt (0) es igual al recuento de registros en la base de datos? –

+1

Estamos contando el número de veces que aparece TABLE en el esquema de sqlite. Un conteo de 0 significa que la tabla no existe. Un recuento de 1 significa que la tabla existe. Estos son los únicos dos valores esperados de recuento. –

21

Si está utilizando fmdb, creo que se puede sólo FMDatabaseAdditions importación y utilizar la función bool:

[yourfmdbDatabase tableExists:tableName]. 
+1

¡Asegúrese de importar "FMDatabaseAdditions.h" para utilizar este método o de lo contrario se preguntará por qué lo eliminaron! :) – Will

+0

Aunque esta podría ser una respuesta correcta, la pregunta era sobre sqlite no una biblioteca en particular en un idioma en particular. Creo que la respuesta debería ser proporcionar código sql, no una llamada a uno de los métodos de la biblioteca – nacho4d

1

mediante una consulta SELECT simple es - en mi opinión - muy fiable. Sobre todo, puede verificar la existencia de tablas en muchos tipos diferentes de bases de datos (SQLite/MySQL).

SELECT 1 FROM table; 

Tiene sentido cuando se puede usar otro mecanismo fiable para determinar si la consulta tuvo éxito (por ejemplo, se consulta una base de datos a través de QSqlQuery en Qt).

6

Aquí es la función que he utilizado:

Dado un objeto SQLDatabase = db

public boolean exists(String table) { 
    try { 
     db.query("SELECT * FROM " + table); 
     return true; 
    } catch (SQLException e) { 
     return false; 
    } 
} 
+1

. Tristemente tuve que usar esto en mi aplicación de Android porque descubrí que los dispositivos Samsung no usan la estructura de tabla estándar sqlite_master que todo el mundo de lo contrario está trabajando con. –

6

Usar este código:

SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName'; 

Si el recuento de matriz devuelta es igual a 1 que significa la mesa existe De lo contrario, no existe.

22

Los nombres de las tablas SQLite no distinguen entre mayúsculas y minúsculas, pero la comparación distingue entre mayúsculas y minúsculas por defecto. Para que esto funcione correctamente en todos los casos, debe agregar COLLATE NOCASE.

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE 
10

Tenga en cuenta que para comprobar si existe una tabla en la base de datos TEMP, debe utilizar sqlite_temp_master en lugar de sqlite_master:

SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name'; 
24

Uso:

PRAGMA table_info(your_table_name) 

Si la tabla resultante está vacía entonces your_table_name no existe.

Documentación:

PRAGMA schema.table_info (nombre-tabla);

Este pragma devuelve una fila para cada columna en la tabla indicada. Las columnas en el conjunto de resultados incluyen el nombre de la columna, el tipo de datos, si la columna puede ser NULL o no, y el valor predeterminado para la columna. La columna "pk" en el conjunto de resultados es cero para las columnas que no son parte de la clave principal, y es el índice de la columna en la clave principal para las columnas que forman parte de la clave principal.

La tabla nombrada en table_info pragma también puede ser una vista.

Ejemplo de salida:

cid|name|type|notnull|dflt_value|pk 
0|id|INTEGER|0||1 
1|json|JSON|0||0 
2|name|TEXT|0||0 
+0

Esta es una gran manera de determinar si existe una tabla en Python. –

+0

o formularios de Xamarin – SerenityNow

+0

Esta es una excelente forma de obtener las definiciones de columna programáticamente – w00t

3

Uso

SELECT 1 FROM table LIMIT 1; 

para prevenir todos los registros de ser leído.

+0

Esto devuelve NULL si la tabla existe pero no tiene ningún registro. – radiospiel

+0

Si la tabla no existe, arrojará un error. Atrapa eso, y sabes que no existe. – luckydonald

+0

utilizando el manejo de errores ya que el control de flujo generalmente no se considera una mejor práctica. Esto probablemente debería ser evitado. –

32

Si usted está recibiendo una "tabla ya existe" error, hacer cambios en la cadena SQL de la siguiente manera:

CREATE table IF NOT EXISTS table_name (para1,para2); 

De esta manera se pueden evitar las excepciones.

0

Este es mi código para SQLite Cordova:

get_columnNames('LastUpdate', function (data) { 
    if (data.length > 0) { // In data you also have columnNames 
     console.log("Table full"); 
    } 
    else { 
     console.log("Table empty"); 
    } 
}); 

Y el otro:

function get_columnNames(tableName, callback) { 
    myDb.transaction(function (transaction) { 
     var query_exec = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name ='" + tableName + "'"; 
     transaction.executeSql(query_exec, [], function (tx, results) { 
      var columnNames = []; 
      var len = results.rows.length; 
      if (len>0){ 
       var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(','); ///// RegEx 
       for (i in columnParts) { 
        if (typeof columnParts[i] === 'string') 
         columnNames.push(columnParts[i].split(" ")[0]); 
       }; 
       callback(columnNames); 
      } 
      else callback(columnNames); 
     }); 
    }); 
} 
0

pensé que había puesto mis 2 centavos a esta discusión, aunque sea más viejo .. Esta consulta devuelve escalar 1 si la tabla existe y 0 en caso contrario.

select 
    case when exists 
     (select 1 from sqlite_master WHERE type='table' and name = 'your_table') 
     then 1 
     else 0 
    end as TableExists 
Cuestiones relacionadas