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?
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}';
Où {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
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
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;
}
Vous pouvez essayer:
SELECT name FROM sqlite_master WHERE name='table_name'
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.
Voir ce:
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
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
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
Si vous utilisez fmdb, je pense que vous pouvez juste importation FMDatabaseAdditions et utiliser la fonction bool:
[yourfmdbDatabase tableExists:tableName].
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"
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';
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;
}
}
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.
Utiliser
SELECT 1 FROM table LIMIT 1;
Pour empêcher la lecture de tous les enregistrements.
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).
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'
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);
});
});
}
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