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?
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}';
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.-à-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;
}
Tu pourrais essayer:
SELECT name FROM sqlite_master WHERE name='table_name'
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.
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
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
Voir this :
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
Si vous utilisez fmdb , je pense que vous pouvez simplement importer 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és est égal à 1, cela signifie que la table existe. Sinon, ça n'existe pas.
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);
}
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 ).
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'
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.
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
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)
}
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);
});
});
}