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

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

原因如下:

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

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

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

或者我的方法有意义吗?


当前回答

如果你得到一个"table already exists"错误,在SQL字符串中做如下修改:

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

这样可以避免异常。

其他回答

我现在在c#中发现的最可靠的方法是使用最新的SQLite -net-pcl nuget包(1.5.231),它使用SQLite 3,如下所示:

var result = database.GetTableInfo(tableName);
if ((result == null) || (result.Count == 0))
{
    database.CreateTable<T>(CreateFlags.AllImplicit);
}

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

参见(7)如何在SQLite FAQ中列出SQLite数据库中包含的所有表/索引:

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

这是我的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);
        });
    });
}

Use

SELECT 1 FROM table LIMIT 1;

防止所有记录被读取。