我如何可靠地在SQLite中检查特定的用户表是否存在?
我并不是要求使用不可靠的方法,比如检查表上的“select *”是否返回错误(这是一个好主意吗?)
原因如下:
在我的程序中,我需要创建并填充一些表,如果它们还不存在的话。
如果它们已经存在,我需要更新一些表。
我是否应该采取其他路径来表示已经创建了相关的表-例如,通过在磁盘上的程序初始化/设置文件中创建/放置/设置某个标志?
或者我的方法有意义吗?
我如何可靠地在SQLite中检查特定的用户表是否存在?
我并不是要求使用不可靠的方法,比如检查表上的“select *”是否返回错误(这是一个好主意吗?)
原因如下:
在我的程序中,我需要创建并填充一些表,如果它们还不存在的话。
如果它们已经存在,我需要更新一些表。
我是否应该采取其他路径来表示已经创建了相关的表-例如,通过在磁盘上的程序初始化/设置文件中创建/放置/设置某个标志?
或者我的方法有意义吗?
当前回答
一种变体是使用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;
}
其他回答
这是我使用的函数:
给定SQLDatabase Object = db
public boolean exists(String table) {
try {
db.query("SELECT * FROM " + table);
return true;
} catch (SQLException e) {
return false;
}
}
R DBI包中的函数dbExistsTable()为R程序员简化了这个问题。请看下面的例子:
library(DBI)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
# let us check if table iris exists in the database
dbExistsTable(con, "iris")
### returns FALSE
# now let us create the table iris below,
dbCreateTable(con, "iris", iris)
# Again let us check if the table iris exists in the database,
dbExistsTable(con, "iris")
### returns TRUE
我想补充Diego Vélez关于PRAGMA声明的回答。
从https://sqlite.org/pragma.html我们可以得到一些有用的函数,可以返回关于我们数据库的信息。 在此,我引用以下内容:
例如,索引中有关列的信息可以使用index_info pragma读取,如下所示: 编译指示index_info(“idx52”); 或者,可以使用以下方法读取相同的内容: SELECT * FROM pragma_index_info('idx52'); 表值函数格式的优点是查询可以只返回PRAGMA列的一个子集,可以包含WHERE子句,可以使用聚合函数,并且表值函数可以只是连接中的几个数据源之一……
Diego的回答给了PRAGMA table_info(table_name)一个选项,但这在您的其他查询中没有多大用处。
所以,要回答OPs问题并改进diego的回答,你可以做
SELECT * FROM pragma_table_info('table_name');
或者更好,
SELECT name FROM pragma_table_list('table_name');
如果你想模仿poorluzer投票最多的答案。
SQLite表名不区分大小写,但是默认情况下比较是区分大小写的。为了在所有情况下都能正常工作,需要添加COLLATE NOCASE。
SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE
c++函数检查db和所有附加的数据库是否存在表和列(可选)。
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;
}
编辑:最近发现了sqlite3_table_column_metadata函数。因此
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;}