Comment puis-je vérifier dans SQLite si une table existe?

Comment puis-je, de manière fiable , vérifier dans SQLite, si une table utilisateur particulière existe?

Je ne demande pas de moyens peu fiables comme 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 comme ceci:

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

S'ils existent déjà, j'ai besoin de mettre à jour certaines tables.

Devrais-je prendre un autre chemin à la place de signal que les tables en question ont déjà été créées - disons par exemple, en créant/mettant/définissant un certain drapeau dans mon fichier d'initialisation/paramètres du programme sur le disque ou quelque chose?

Ou mon approche a-t-elle du sens?

771
demandé sur Peter Mortensen 2009-10-21 18:22:10

18 réponses

J'ai manqué 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

876
répondu PoorLuzer 2018-03-19 04:16:41

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
485
répondu arthur johnston 2013-05-31 02:50:56

Une variante consisterait à utiliser SELECT COUNT (*) au lieu de SELECT NAME, c'est-à-dire

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

Cela retournera 0, si la table n'existe pas, 1 si c'est le cas. Cela est probablement utile dans votre programmation, car un résultat numérique est plus rapide / plus facile à traiter. Ce qui suit illustre comment vous le feriez dans Android en utilisant 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;
}
156
répondu Stephen Quan 2017-07-06 00:32:56

Vous pouvez essayer:

SELECT name FROM sqlite_master WHERE name='table_name'
39
répondu Galwegian 2009-10-21 14:25:51

Si vous obtenez une erreur "table already exists", Modifiez la chaîne SQL comme suit:

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

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

34
répondu Rakesh Chaudhari 2017-03-03 17:05:47

Voir ce:

SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
27
répondu Anton Gogolev 2009-10-21 14:25:32

Les noms de table SQLite sont insensibles à 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
27
répondu Brice M. Dempsey 2014-02-22 18:07:00

Utilisation:

PRAGMA table_info(your_table_name)

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

Documentation:

Schéma PRAGMA.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 qui ne font pas partie de la clé primaire, et est l'index de la colonne de la clé primaire pour les colonnes qui font 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
27
répondu Diego Vélez 2017-11-01 15:50:16

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

[yourfmdbDatabase tableExists:tableName].
22
répondu user655489 2015-10-26 12:10:18

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
répondu pacheco 2017-03-03 16:59:00

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
répondu Scott Deerwester 2014-04-24 15:49:33

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;
    }
}
6
répondu DroidGrailer 2012-06-11 17:56:33

Utilisez ce code:

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

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

6
répondu asmad 2017-03-03 17:01:38

Utiliser

SELECT 1 FROM table LIMIT 1;

Pour empêcher la lecture de tous les enregistrements.

3
répondu Franz Fahrenkrog Petermann 2014-10-28 17:27:34

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

SELECT 1 FROM table;

Il est logique lorsque vous pouvez 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
répondu Grz 2017-03-03 17:00:32

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 'table_name' est votre nom de table ce 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érifiez

  SELECT name FROM sqlite_master WHERE name='country'
1
répondu Anantha krishnan 2018-08-02 10:14:55

C'est 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
répondu Zappescu 2017-03-03 17:07:36

Je pensais mettre mes 2 cents à cette discussion, même si elle est plutôt ancienne.. Cette requête renvoie scalaire 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
répondu Piotr Rodak 2017-06-10 22:13:28