如何检查SQLite是否存在一个表?

我如何可靠地检查SQLite中是否存在特定的用户表?

我不是要求不可靠的方法,如检查表上的“select *”是否返回错误(这是一个好主意?)。

原因是这样的:

在我的程序中,我需要创build并填充一些表,如果它们不存在的话。

如果他们已经存在,我需要更新一些表格。

我应该采取一些其他的途径,而不是信号,表格已经被创build – 例如,通过创build/放置/设置一个特定的标志在我的程序初始化/设置文件在磁盘上或什么?

或者我的方法是否有意义?

我错过了那个FAQ条目。

无论如何,为了将来的参考,完整的查询是:

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

如果您使用SQLite版本3.3+,您可以轻松地创build一个表:

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

以同样的方式,您可以删除一个表,只要它存在通过使用:

 drop table if exists TableName 

一个变化是使用SELECT COUNT(*)而不是SELECT NAME,即

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

这将返回0,如果表不存在,则返回1。 这在您的编程中可能是有用的,因为数值结果更快/更容易处理。 下面的例子说明了如何在Android中使用SQLiteDatabase,Cursor,rawQuery和参数来做到这一点。

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

你可以尝试:

 SELECT name FROM sqlite_master WHERE name='table_name' 

如果您收到“表已存在”错误,请在SQLstring中进行更改,如下所示:

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

这样可以避免例外。

使用:

 PRAGMA table_info(your_table_name) 

如果结果表为空,那么your_table_name不存在。

文档:

PRAGMA schema.table_info(table-name);

该编译指示为指定表中的每个列返回一行。 结果集中的列包括列名称,数据types,列是否可以为NULL以及列的默认值。 结果集中的“pk”列对于不是主键一部分的列是零,并且是作为主键的一部分的列的主键列中的索引。

在table_info附注中命名的表也可以是一个视图。

示例输出:

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

看到这个 :

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

SQLite表名不区分大小写,但默认情况下比较是区分大小写的。 为了在所有情况下都能正常工作,您需要添加COLLATE NOCASE

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

如果你使用fmdb ,我想你可以导入FMDatabaseAdditions并使用bool函数:

 [yourfmdbDatabase tableExists:tableName]. 

如果表存在,则下面的代码返回1;如果表不存在,则返回0。

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

请注意,要检查TEMP数据库中是否存在表,您必须使用sqlite_temp_master而不是sqlite_master

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

这是我使用的function:

给定一个SQLDatabase对象= db

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

使用此代码:

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

如果返回的数组数等于1,则表示该表存在。 否则它不存在。

使用

 SELECT 1 FROM table LIMIT 1; 

以防止所有logging被读取。

在我看来,使用简单的SELECT查询相当可靠。 最重要的是它可以检查许多不同数据库types(SQLite / MySQL)中的表存在情况。

 SELECT 1 FROM table; 

当您可以使用其他可靠的机制来确定查询是否成功时(例如,您通过Qt中的 QSqlQuery查询数据库),这是有道理的。

这是我的代码为SQLitecordova:

 get_columnNames('LastUpdate', function (data) { if (data.length > 0) { // In data you also have columnNames console.log("Table full"); } else { console.log("Table empty"); } }); 

而另一个:

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

我想我会把我的2美分这个讨论,即使它是相当古老的..这个查询返回标量1,如果表存在,否则返回0。

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