Hoe kan ik, betrouwbaar, in SQLite controleren of een bepaalde gebruikerstabel bestaat?
Ik vraag niet om onbetrouwbare manieren, zoals controleren of een “select *” op de tafel een fout heeft opgeleverd of niet (is dit zelfs een goed idee?).
De reden is als volgt:
In mijn programma moet ik een aantal tabellen maken en vervolgens vullen als ze nog niet bestaan.
Als ze al bestaan, moet ik enkele tabellen bijwerken.
Moet ik in plaats daarvan een ander pad nemen om aan te geven dat de betreffende tabellen al zijn gemaakt, bijvoorbeeld door een bepaalde vlag aan te maken/te plaatsen/in te stellen in mijn programma-initialisatie-/instellingenbestand op schijf of zoiets?
Of is mijn aanpak logisch?
Antwoord 1, autoriteit 100%
Ik heb dat item met veelgestelde vragen gemist.
Hoe dan ook, voor toekomstig gebruik, de volledige vraag is:
SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';
Waar {table_name}
de naam is van de tabel die moet worden gecontroleerd.
Documentatiesectie ter referentie: Databasebestandsformaat. 2.6. Opslag van het SQL-databaseschema
- Hiermee wordt een lijst met tabellen geretourneerd met de opgegeven naam; dat wil zeggen, de cursor heeft een telling van 0 (bestaat niet) of een telling van 1 (bestaat wel)
Antwoord 2, autoriteit 55%
Als u SQLite versie 3.3+ gebruikt, kunt u eenvoudig een tabel maken met:
create table if not exists TableName (col1 typ1, ..., colN typN)
Op dezelfde manier kunt u een tabel alleen verwijderen als deze bestaat met:
drop table if exists TableName
Antwoord 3, autoriteit 17%
Een variatie zou zijn om SELECT COUNT(*) te gebruiken in plaats van SELECT NAME, d.w.z.
SELECT count(*) FROM sqlite_master WHERE type='table' AND name='table_name';
Dit geeft 0 terug als de tabel niet bestaat, 1 als dat wel het geval is. Dit is waarschijnlijk handig in uw programmering, aangezien een numeriek resultaat sneller / gemakkelijker te verwerken is. Het volgende illustreert hoe u dit in Android zou doen met SQLiteDatabase, Cursor, rawQuery met parameters.
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;
}
Antwoord 4, autoriteit 5%
Je zou kunnen proberen:
SELECT name FROM sqlite_master WHERE name='table_name'
Antwoord 5, autoriteit 4%
Zie (7) Hoe vermeld ik alle tabellen/indices in een SQLite-databasein de SQLite FAQ:
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
Antwoord 6, autoriteit 3%
Gebruik:
PRAGMA table_info(your_table_name)
Als de resulterende tabel leeg is, bestaat your_table_name
niet.
Documentatie:
PRAGMA schema.table_info(tabelnaam);
Dit pragma retourneert één rij voor elke kolom in de genoemde tabel. Kolommen in de resultatenset bevatten de kolomnaam, het gegevenstype, of de kolom NULL kan zijn of niet, en de standaardwaarde voor de kolom. De kolom ‘pk’ in de resultatenset is nul voor kolommen die geen deel uitmaken van de primaire sleutel en is de index van de kolom in de primaire sleutel voor kolommen die deel uitmaken van de primaire sleutel.
De tabel met de naam in het table_info pragma kan ook een weergave zijn.
Voorbeelduitvoer:
cid|name|type|notnull|dflt_value|pk
0|id|INTEGER|0||1
1|json|JSON|0||0
2|name|TEXT|0||0
Antwoord 7, autoriteit 3%
Als je de foutmelding “tabel bestaat al” krijgt, breng dan wijzigingen aan in de SQL-string zoals hieronder:
CREATE table IF NOT EXISTS table_name (para1,para2);
Op deze manier kunt u de uitzonderingen vermijden.
Antwoord 8, autoriteit 3%
SQLite-tabelnamen zijn niet hoofdlettergevoelig, maar vergelijking is standaard hoofdlettergevoelig. Om dit in alle gevallen correct te laten werken, moet u COLLATE NOCASE
toevoegen.
SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE
Antwoord 9, autoriteit 2%
Als je fmdbgebruikt, denk ik dat je gewoon FMDatabaseAdditions kunt importerenen de bool kunt gebruiken functie:
[yourfmdbDatabase tableExists:tableName].
Antwoord 10
De volgende code retourneert 1 als de tabel bestaat of 0 als de tabel niet bestaat.
SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table"
Antwoord 11
Houd er rekening mee dat om te controleren of een tabel in de TEMP-database bestaat, u sqlite_temp_master
moet gebruiken in plaats van sqlite_master
:
SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';
Antwoord 12
Dit is de functie die ik heb gebruikt:
Gegeven een SQLDatabase-object = db
public boolean exists(String table) {
try {
db.query("SELECT * FROM " + table);
return true;
} catch (SQLException e) {
return false;
}
}
Antwoord 13
Gebruik deze code:
SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName';
Als het aantal geretourneerde arrays gelijk is aan 1 betekent dit dat de tabel bestaat. Anders bestaat het niet.
Antwoord 14
class 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
Opmerking: dit werkt nu op mijn Mac met Python 3.7.1
Antwoord 15
U kunt de volgende query schrijven om het bestaan van de tabel te controleren.
SELECT name FROM sqlite_master WHERE name='table_name'
Hier is ‘table_name’ je tabelnaam die je hebt gemaakt. Bijvoorbeeld
CREATE TABLE IF NOT EXISTS country(country_id INTEGER PRIMARY KEY AUTOINCREMENT, country_code TEXT, country_name TEXT)"
en controleer
SELECT name FROM sqlite_master WHERE name='country'
Antwoord 16
Gebruik
SELECT 1 FROM table LIMIT 1;
om te voorkomen dat alle records worden gelezen.
Antwoord 17
De meest betrouwbare manier die ik op dit moment in C# heb gevonden, met het nieuwste sqlite-net-pcl nuget-pakket (1.5.231) dat SQLite 3 gebruikt, is als volgt:
var result = database.GetTableInfo(tableName);
if ((result == null) || (result.Count == 0))
{
database.CreateTable<T>(CreateFlags.AllImplicit);
}
Antwoord 18
Het gebruik van een eenvoudige SELECT-query is – naar mijn mening – redelijk betrouwbaar. Bovenal kan het de aanwezigheid van tabellen in veel verschillende databasetypes (SQLite / MySQL) controleren.
SELECT 1 FROM table;
Het is logisch wanneer u een ander betrouwbaar mechanisme kunt gebruiken om te bepalen of de zoekopdracht is geslaagd (u zoekt bijvoorbeeld een database op via QSqlQuery in Qt).
Antwoord 19
c++-functie controleert db en alle gekoppelde databases op het bestaan van tabel en (optioneel) kolom.
bool exists(sqlite3 *db, string tbl, string col="1")
{
sqlite3_stmt *stmt;
bool b = sqlite3_prepare_v2(db, ("select "+col+" from "+tbl).c_str(),
-1, &stmt, 0) == SQLITE_OK;
sqlite3_finalize(stmt);
return b;
}
Bewerken: onlangs de functie sqlite3_table_column_metadata ontdekt. Vandaar
bool exists(sqlite3* db,const char *tbl,const char *col=0)
{return sqlite3_table_column_metadata(db,0,tbl,col,0,0,0,0,0)==SQLITE_OK;}
Antwoord 20
U kunt ook db-metadata gebruiken om te controleren of de tabel bestaat.
DatabaseMetaData md = connection.getMetaData();
ResultSet resultSet = md.getTables(null, null, tableName, null);
if (resultSet.next()) {
return true;
}
Antwoord 21
Dit is mijn code voor 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");
}
});
En de andere:
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);
});
});
}
Antwoord 22
Ik dacht dat ik mijn 2 cent in deze discussie zou steken, ook al is het een vrij oude..
Deze query retourneert scalaire 1 als de tabel bestaat en 0 anders.
select
case when exists
(select 1 from sqlite_master WHERE type='table' and name = 'your_table')
then 1
else 0
end as TableExists
Antwoord 23
Tabel bestaat of niet in database in 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)
}
Antwoord 24
Mijn voorkeursaanpak:
SELECT "name" FROM pragma_table_info("table_name") LIMIT 1;
Als u een rijresultaat krijgt, bestaat de tabel. Dit is beter (voor mij) dan controleren met sqlite_master
, omdat het ook bijgevoegde en tijdelijke databases zal controleren.
Antwoord 25
Als je het uitvoert met het python-bestand en uiteraard sqlite3 gebruikt. Open de opdrachtprompt of bash wat je ook gebruikt, gebruik
- python3 file_name.pyeerst waarin uw sql-code is geschreven.
- Voer vervolgens sqlite3 bestandsnaam.dbuit.
- .tabledit commando geeft tabellen als ze bestaan.