SQLite3并不总是正常工作(无法准备或执行查询)

时间:2016-12-09 14:47:58

标签: ios swift sqlite

我正在使用MacMini进行swift开发,我正在iPhone 6S上进行测试。

我尝试安装Sqlite-wrappers(SQLite.swift,fmdb),但他们都在启动时崩溃了我的应用程序。所以我使用纯sqlite3-API。

首先,我创建了一个指向DB的指针,并将其作为静态变量提供。

static var db: OpaquePointer? = nil
.....
sqlite3_open(fileURL.path, &db)

但我有时会遇到Bad_Access崩溃。搜索网络。发现"不要在不同的线程中使用1个指针"。

所以现在我在不同的线程中使用open-statement创建一个指针,总是一个sqlite3_reset,一个finalize然后我关闭它。

static func getDBPointer() -> OpaquePointer? {
    var db: OpaquePointer? = nil
    if sqlite3_open(dbFile, &db) != SQLITE_OK {
        print("error opening database")
    } else {
        print("******************* DB opened")
    }
    return db
}

工作好几天,没有问题,没有Bad_Access。

但现在所有数据库都表现得非常奇怪。 它运行良好一分钟,然后我无法插入或更新行,下一个语句再次正常工作。 "从表格中删除*"大多数时候都没问题,但偶尔也会失败。所有sqlite3_prepare_v2() - 语句工作正常,我看不到语法问题。 在接下来的尝试中(相同的陈述,所有信息都适当的数据)我几乎总是"准备失败......"

这是一个简短的代码示例:

let db = getDBPointer()

let insertStatementString = "INSERT INTO vorstellung_info (vorstellung_nr,datum,vorstellung,haus,autor) VALUES (\(vorst_num),\(vorst_datum),'\(vorstellung_name)','\(vorst_haus)','\(vorst_autor)');"

print("Insert vorstellung string: \(insertStatementString)")

var insertStatement: OpaquePointer? = nil

if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
    if sqlite3_step(insertStatement) == SQLITE_DONE {
        print("Done well.")
    } else {
        print("Could not insert row in vorstellung_info: \(insertStatementString)")
    }
} else {
    print("INSERT statement to vorstellung_info could not be prepared.")
}
sqlite3_finalize(insertStatement)
sqlite3_close_v2(db)

输出:

Insert vorstellung string: INSERT INTO vorstellung_info (vorstellung_nr,datum,vorstellung,haus,autor) VALUES (45127,1481382000000,'TEST-WantToSee','Thats the place','Interesting author');
Could not insert row in vorstellung_info: INSERT INTO vorstellung_info (vorstellung_nr,datum,vorstellung,haus,autor) VALUES (45127,1481382000000,'TEST-WantToSee','Thats the place','Interesting author');

正如我之前所说:有时甚至准备声明都失败了。

此示例的create table语句:

let createVorstellungInfo = "CREATE TABLE IF NOT EXISTS vorstellung_info(" +
            "vorstellung_nr INT," +
            "datum INT," +
            "vorstellung TEXT," +
            "haus TEXT," +
        "autor TEXT);"

该计划有很多"会话"通过会话使用服务器,因此大多数非select语句在session.task或静态函数中都是异步的,由这样的任务调用。

编辑:

添加"字符串(cString:sqlite3_errmsg(db))"到任何可能的位置

"无法准备":

SELECT statement could not be prepared: SELECT * from rechnung_vorst where rechnung_nr = 9868681 AND vorstellung_nr = 45138;
------------------------- 
database is locked

"无法加载"

Veranstalter could not get loaded: SELECT veranstalter_nname, veranstalter_vname, veranstalter_uid, veranstalter_ort, veranstalter_plz, veranstalter_str FROM veranstalter WHERE veranstalter_nr = 2062491;
------------------------- 
unknown error

这些只是消息的两个例子。 顺便说一下:花了我4-5次尝试获取这些消息(所有这些都在一次尝试中)。首先,它工作正常,然后这些错误,然后再次工作......

1 个答案:

答案 0 :(得分:0)

多线程SQLite很难。这非常有趣,我永远不会说你不应该试图自己解决这个挑战。但如果您想在其他地方度过时间,我建议您查看GRDB.swift。它提供了比其他库更多的并发保证:http://github.com/groue/GRDB.swift#concurrency