我如何可靠地在SQLite中检查特定的用户表是否存在?
我不是在要求不可靠的方法,例如检查表上的“ select *”是否返回错误(这甚至是个好主意吗?)。
原因是这样的:
在我的程序中,我需要创建然后填充一些表(如果它们尚不存在)。
如果它们已经存在,则需要更新一些表。
我是否应该采取其他路径来表示已创建相关表,例如,通过在磁盘上的程序初始化/设置文件中创建/放置/设置某个标志,或其他方式来表示此表?
还是我的方法有意义?
#1楼
如果您使用FMDB ,我觉得你可以导入FMDatabaseAdditions并使用布尔函数:
[yourfmdbDatabase tableExists:tableName].
#2楼
我认为,使用简单的SELECT查询非常可靠。 最重要的是,它可以检查许多不同数据库类型(SQLite / MySQL)中表的存在。
SELECT 1 FROM table;
当您可以使用其他可靠的机制确定查询是否成功(例如,通过Qt中的 QSqlQuery查询数据库)时,这才有意义。
#3楼
这是我使用的功能:
给定一个SQLDatabase Object = db
public boolean exists(String table) {
try {
db.query("SELECT * FROM " + table);
return true;
} catch (SQLException e) {
return false;
}
}
#4楼
看到这个 :
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
#5楼
您可以尝试:
SELECT name FROM sqlite_master WHERE name='table_name'
#6楼
我错过了该常见问题解答条目。
无论如何,完整的查询是:
SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';
其中{table_name}
是要检查的表的名称。
供参考的文档部分: 数据库文件格式。 2.6。 SQL数据库架构的存储
- 这将返回具有指定名称的表的列表; 也就是说,游标的计数为0(不存在)或计数为1(存在)
#7楼
使用此代码:
SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName';
如果返回的数组计数等于1,则表示该表存在。 否则它不存在。
#8楼
SQLite表名称不区分大小写,但是默认情况下比较是区分大小写的。 为了在所有情况下都能正常工作,您需要添加COLLATE NOCASE
。
SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE
#9楼
请注意,要检查TEMP数据库中是否存在表,必须使用sqlite_temp_master
而不是sqlite_master
:
SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';
#10楼
采用:
PRAGMA table_info(your_table_name)
如果结果表为空,则your_table_name
不存在。
说明文件:
PRAGMA schema.table_info(表名);
该编译指示为命名表中的每一列返回一行。 结果集中的列包括列名称,数据类型,该列是否可以为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
#11楼
采用
SELECT 1 FROM table LIMIT 1;
以防止读取所有记录。
#12楼
如果收到“表已存在”错误,请在SQL字符串中进行如下更改:
CREATE table IF NOT EXISTS table_name (para1,para2);
这样您可以避免异常。
#13楼
这是我的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");
}
});
而另一个:
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);
});
});
}
#14楼
我以为我会在讨论中投入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
#15楼
您可以编写以下查询来检查表是否存在。
SELECT name FROM sqlite_master WHERE name='table_name'
这里的“ table_name”是您创建的表名。 例如
CREATE TABLE IF NOT EXISTS country(country_id INTEGER PRIMARY KEY AUTOINCREMENT, country_code TEXT, country_name TEXT)"
并检查
SELECT name FROM sqlite_master WHERE name='country'
#16楼
如果您使用的是SQLite 3.3+版本,则可以使用以下命令轻松创建表:
create table if not exists TableName (col1 typ1, ..., colN typN)
以同样的方式,您只能使用以下方法删除表:
drop table if exists TableName
#17楼
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
注意:现在可以在Mac上使用Python 3.7.1的计算机上使用
#18楼
我现在使用最新的sqlite-net-pcl nuget软件包(1.5.231)(使用SQLite 3)在C#中找到的最可靠的方法如下:
var result = database.GetTableInfo(tableName);
if ((result == null) || (result.Count == 0))
{
database.CreateTable<T>(CreateFlags.AllImplicit);
}
#19楼
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)
}
#20楼
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;
}
#21楼
如果表存在,则以下代码返回1;如果表不存在,则返回0。
SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table"
#22楼
一种变化是使用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;
}