如何在 SQLite 中检查表是否存在?

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

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

原因是这样的:

在我的程序中,我需要创建然后填充一些表(如果还不存在)。

如果它们已经存在,则需要更新一些表。

我是否应该采取其他路径来表示已经建立了相关表,例如,通过在磁盘上的程序初始化 / 设置文件中创建 / 放置 / 设置某个标志,等等?

还是我的方法有意义?

答案

我错过了该常见问题解答条目。

无论如何,完整的查询是:

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

其中{table_name}是要检查的表的名称。

供参考的文档部分: 数据库文件格式。 2.6。 SQL 数据库架构的存储

  • 这将返回具有指定名称的表的列表;也就是说,游标的计数为 0(不存在)或计数为 1(存在)

如果您使用的是 SQLite 3.3 + 版本,则可以使用以下命令轻松创建表:

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'

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

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

用:

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

如果遇到 “表已存在” 错误,请在 SQL 字符串中进行如下更改:

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

这样您可以避免异常。

看到这个

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

如果您使用FMDB ,我觉得你可以导入 FMDatabaseAdditions并使用布尔函数:

[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"