web-dev-qa-db-fra.com

Comment vérifier dans SQLite si une table existe?

Comment puis-je, sûrement, vérifier dans SQLite si une table utilisateur particulière existe?

Je ne demande pas de moyens peu fiables, comme de vérifier si un "select *" sur la table a renvoyé une erreur ou non (est-ce même une bonne idée?).

La raison est la suivante:

Dans mon programme, je dois créer puis remplir certaines tables si elles n'existent pas déjà.

S'ils existent déjà, je dois mettre à jour certaines tables.

Devrais-je choisir un autre chemin pour signaler que les tables en question ont déjà été créées - par exemple, en créant/plaçant/définissant un indicateur dans mon fichier d’initialisation/de paramètres de programme sur disque ou quelque chose de ce type?

Ou est-ce que mon approche a du sens?

799
PoorLuzer

J'ai raté cette entrée FAQ.

Quoi qu’il en soit, pour référence future, la requête complète est:

SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';

{table_name} est le nom de la table à vérifier.

Section de documentation pour référence: Format de fichier de base de données. 2.6 Stockage du schéma de base de données SQL

908
PoorLuzer

Si vous utilisez SQLite version 3.3+, vous pouvez facilement créer une table avec: 

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

De la même manière, vous ne pouvez supprimer une table que si elle existe en utilisant:

drop table if exists TableName
502
arthur johnston

Une variante consisterait à utiliser SELECT COUNT (*) au lieu de SELECT NAME, c.-à-d.

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

Cela retournera 0, si la table n'existe pas, 1 s'il existe. Ceci est probablement utile dans votre programmation car un résultat numérique est plus rapide/facile à traiter. Ce qui suit illustre la procédure à suivre dans Android avec SQLiteDatabase, Cursor, rawQuery avec des paramètres.

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;
}
163
Stephen Quan

Tu pourrais essayer:

SELECT name FROM sqlite_master WHERE name='table_name'
39
Galwegian

Si vous obtenez une erreur "la table existe déjà", apportez les modifications dans la chaîne SQL comme ci-dessous:

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

De cette façon, vous pouvez éviter les exceptions.

34
Rakesh Chaudhari

Les noms de table SQLite ne respectent pas la casse, mais la comparaison est sensible à la casse par défaut. Pour que cela fonctionne correctement dans tous les cas, vous devez ajouter COLLATE NOCASE.

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE
32
Brice M. Dempsey

Utilisation:

PRAGMA table_info(your_table_name)

Si la table résultante est vide, alors your_table_name n'existe pas.

Documentation:

PRAGMA schema.table_info (nom de la table);

Ce pragma renvoie une ligne pour chaque colonne de la table nommée. Les colonnes du jeu de résultats incluent le nom de la colonne, le type de données, si la colonne peut être NULL ou non, et la valeur par défaut de la colonne. La colonne "pk" dans le jeu de résultats est zéro pour les colonnes ne faisant pas partie de la clé primaire et correspond à l'index de la colonne de la clé primaire pour les colonnes faisant partie de la clé primaire.

La table nommée dans le pragma table_info peut également être une vue.

Exemple de sortie:

cid|name|type|notnull|dflt_value|pk
0|id|INTEGER|0||1
1|json|JSON|0||0
2|name|TEXT|0||0
30
Diego Vélez

Voir this :

SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
28
Anton Gogolev

Si vous utilisez fmdb , je pense que vous pouvez simplement importer FMDatabaseAdditions et utiliser la fonction bool:

[yourfmdbDatabase tableExists:tableName].
22
user655489

Le code suivant renvoie 1 si la table existe ou 0 si la table n'existe pas.

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

Notez que pour vérifier si une table existe dans la base de données TEMP, vous devez utiliser sqlite_temp_master au lieu de sqlite_master:

SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';
10
Scott Deerwester

Voici la fonction que j'ai utilisée: 

Étant donné un objet SQLDatabase = db

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

Utilisez ce code:

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

Si le nombre de tableaux retournés est égal à 1, cela signifie que la table existe. Sinon, ça n'existe pas.

7
asmad

Utilisation

SELECT 1 FROM table LIMIT 1;

pour empêcher la lecture de tous les enregistrements.

Le moyen le plus fiable que j'ai trouvé en C # à l'heure actuelle, à l'aide du dernier package de nuget sqlite-net-pcl (1.5.231) utilisant SQLite 3, est le suivant:

var result = database.GetTableInfo(tableName);
        if ((result == null) || (result.Count == 0))
        {
            database.CreateTable<T>(CreateFlags.AllImplicit);
        }
2
Matthew Joughin

L'utilisation d'une simple requête SELECT est, à mon avis, assez fiable. Surtout, il peut vérifier l'existence d'une table dans de nombreux types de bases de données (SQLite/MySQL).

SELECT 1 FROM table;

Il est judicieux d'utiliser un autre mécanisme fiable pour déterminer si la requête a réussi (par exemple, vous interrogez une base de données via QSqlQuery dans Qt ).

1
Grz

Vous pouvez écrire la requête suivante pour vérifier l'existence de la table.

SELECT name FROM sqlite_master WHERE name='table_name'

Ici 'nom_table' est le nom de votre table que vous avez créé. Par exemple

 CREATE TABLE IF NOT EXISTS country(country_id INTEGER PRIMARY KEY AUTOINCREMENT, country_code TEXT, country_name TEXT)"

et vérifie

  SELECT name FROM sqlite_master WHERE name='country'
1
Anantha krishnan

classe CPhoenixDatabase ():

def __init__(self, dbname):
    self.dbname = dbname
    self.conn = sqlite3.connect(dbname)

def is_table(self, table_name):
    """ This method seems to be working now"""
    query = "SELECT name from sqlite_master WHERE type='table' AND name='{" + table_name + "}';"
    cursor = self.conn.execute(query)
    result = cursor.fetchone()
    if result == None:
        return False
    else:
        return True

Remarque: cela fonctionne maintenant sur mon Mac avec Python 3.7.1.

0
Douglas Goodall

Je pensais que je mettrais mes 2 centimes dans cette discussion, même si elle est plutôt ancienne… Cette requête renvoie scalar 1 si la table existe et 0 sinon.

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

La table existe ou pas dans la base de données dans Swift

func tableExists(_ tableName:String) -> Bool {
        sqlStatement = "SELECT name FROM sqlite_master WHERE type='table' AND name='\(tableName)'"
        if sqlite3_prepare_v2(database, sqlStatement,-1, &compiledStatement, nil) == SQLITE_OK {
            if sqlite3_step(compiledStatement) == SQLITE_ROW {
                return true
            }
            else {
                return false
            }
        }
        else {
            return false
        }
            sqlite3_finalize(compiledStatement)
    }
0
CSE 1994

Voici mon code pour 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");
    }
});

Et l'autre:

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
Zappescu