Come posso verificare in SQLite se esiste una tabella?

Come posso, in modo affidabile , verificare in SQLite se esiste una tabella utente specifica?

Non sto chiedendo modi inaffidabili come controllare se un “select *” sul tavolo ha restituito un errore o meno (è questa anche una buona idea?).

Il motivo è questo:

Nel mio programma, ho bisogno di creare e quindi compilare alcune tabelle se non esistono già.

Se esistono già, devo aggiornare alcune tabelle.

Dovrei prendere qualche altro percorso per segnalare che le tabelle in questione sono già state create – ad esempio, creando / mettendo / impostando un determinato flag nel file di inizializzazione / impostazioni del mio programma su disco o qualcosa del genere?

O il mio approccio ha senso?

Ho perso la voce FAQ.

Ad ogni modo, per riferimento futuro, la query completa è:

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

Dove {table_name} è il nome della tabella da controllare.

Sezione di documentazione per riferimento: Formato file database. 2.6. Memorizzazione dello schema del database SQL

Se stai usando SQLite versione 3.3+ puoi facilmente creare una tabella con:

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

Allo stesso modo, puoi rimuovere una tabella solo se esiste usando:

 drop table if exists TableName 

Una variante sarebbe usare SELECT COUNT (*) invece di SELECT NAME, es

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

Questo restituirà 0, se la tabella non esiste, 1 se lo fa. Questo è probabilmente utile nella programmazione poiché un risultato numerico è più veloce / più facile da elaborare. Quanto segue illustra come farlo in Android utilizzando SQLiteDatabase, Cursor, rawQuery con parametri.

 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; } 

Potresti provare:

 SELECT name FROM sqlite_master WHERE name='table_name' 

Se stai ricevendo un errore “la tabella esiste già”, apporta le modifiche nella stringa SQL come di seguito:

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

In questo modo puoi evitare le eccezioni.

Uso:

 PRAGMA table_info(your_table_name) 

Se la tabella risultante è vuota, your_table_name non esiste.

Documentazione:

PRAGMA schema.table_info (nome-tabella);

Questo pragma restituisce una riga per ogni colonna nella tabella denominata. Le colonne nel set di risultati includono il nome della colonna, il tipo di dati, se la colonna può essere NULL e il valore predefinito per la colonna. La colonna “pk” nel set di risultati è zero per le colonne che non fanno parte della chiave primaria ed è l’indice della colonna nella chiave primaria per le colonne che fanno parte della chiave primaria.

La tabella nominata nel pragma table_info può anche essere una vista.

Esempio di output:

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

I nomi delle tabelle SQLite non fanno distinzione tra maiuscole e minuscole, ma per impostazione predefinita il confronto è case sensitive. Per farlo funzionare correttamente in tutti i casi è necessario aggiungere COLLATE NOCASE .

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

Vedi questo :

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

Se stai usando fmdb , penso che puoi semplicemente importare FMDatabaseAdditions e usare la funzione bool:

 [yourfmdbDatabase tableExists:tableName]. 

Il seguente codice restituisce 1 se la tabella esiste o 0 se la tabella non esiste.

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

Nota che per verificare se esiste una tabella nel database TEMP, devi usare sqlite_temp_master invece di sqlite_master :

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

Ecco la funzione che ho usato:

Dato un object SQLDatabase = db

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

Usa questo codice:

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

Se il conteggio dell’array restituito è uguale a 1 significa che la tabella esiste. Altrimenti non esiste.

Uso

 SELECT 1 FROM table LIMIT 1; 

per impedire che tutti i record vengano letti.

L’utilizzo di una semplice query SELECT è, a mio parere, abbastanza affidabile. Soprattutto può controllare l’esistenza della tabella in molti tipi di database diversi (SQLite / MySQL).

 SELECT 1 FROM table; 

Ha senso quando è ansible utilizzare un altro meccanismo affidabile per determinare se la query è riuscita (ad esempio, si esegue una query su un database tramite QSqlQuery in Qt ).

È ansible scrivere la seguente query per verificare l’esistenza della tabella.

 SELECT name FROM sqlite_master WHERE name='table_name' 

Qui ‘table_name’ è il nome della tabella che cosa hai creato. Per esempio

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

e controllare

  SELECT name FROM sqlite_master WHERE name='country' 

Questo è il mio codice per 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"); } }); 

E l’altro:

 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); }); }); } 

Ho pensato di mettere i miei 2 centesimi in questa discussione, anche se è piuttosto vecchia .. Questa query restituisce scalare 1 se la tabella esiste e 0 altrimenti.

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