【发布时间】:2018-01-29 13:16:14
【问题描述】:
我需要在现有的SQLite 数据库中插入超过 1,000 条记录。为此,我有一个包含一些静态函数的类,如下所示。
class Application {
static func openDatabase(path: String) -> OpaquePointer? {
var db: OpaquePointer? = nil
if sqlite3_open(path, &db) == SQLITE_OK {
return db
} else {
return nil
}
}
static func createTable(path: String) {
let open = openDatabase(path: path)
var createTableStatement: OpaquePointer? = nil
let sqlCreate = "CREATE TABLE IF NOT EXISTS data (ID INTEGER PRIMARY KEY AUTOINCREMENT, year text, month text, day text, x1 text, x2 text, x3 text)"
if sqlite3_prepare_v2(open, sqlCreate, -1, &createTableStatement, nil) == SQLITE_OK {
if sqlite3_step(createTableStatement) == SQLITE_DONE {
print("Table created.")
} else {
print("Table could not be created.")
}
} else {
print("CREATE TABLE statement could not be prepared.")
}
sqlite3_finalize(createTableStatement)
}
static func insertRecord(path: String, year: String, month: String, day: String) {
let open = openDatabase(path: path)
var insertStatement: OpaquePointer? = nil
let sqlInsert = "INSERT INTO data (year, month, day) VALUES (?, ?, ?)"
if sqlite3_prepare_v2(open, sqlInsert, -1, &insertStatement, nil) == SQLITE_OK {
let yearStr = year as NSString
let monthStr = month as NSString
let dayStr = day as NSString
sqlite3_bind_text(insertStatement, 1, yearStr.utf8String, -1, nil)
sqlite3_bind_text(insertStatement, 2, monthStr.utf8String, -1, nil)
sqlite3_bind_text(insertStatement, 3, dayStr.utf8String, -1, nil)
if sqlite3_step(insertStatement) == SQLITE_DONE {
print("Successfully inserted row.")
} else {
print("Could not insert row.")
}
} else {
print("INSERT statement could not be prepared.")
}
// 5
sqlite3_finalize(insertStatement)
}
}
然后我从AppDelegate 插入记录。如果我第二次运行它以便将记录插入数据库,如下所示,
class AppDelegate: UIResponder, UIApplicationDelegate {
var appFile = String()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
appFile = folderPath(s: 0, name: "Application")
if !pathExists(path: appFile) {
Application.createTable(path: appFile)
} else {
for i in 0..<10 {
for j in 0..<12 {
for k in 0..<31 {
let yearStr = String(i + 2018)
let monthStr = String(j + 1)
let dayStr = String(k + 1)
Application.insertRecord(path: appFile, year: yearStr, month: monthStr, day: dayStr)
}
}
}
}
return true
}
}
将 250 条记录插入数据库后,应用程序将崩溃。调试器说“NSInternalInconsistencyException”它崩溃了,我相信,因为应用程序一次打开 250 个文件。几年前,这不是问题,因为我们可以像这样关闭数据库
sqlite3_close(statement)
应用每次打开一个语句。现在,我们不能。那么我们可以做些什么来一次插入多条记录呢?谢谢。
【问题讨论】:
-
错误信息暗示不允许打开到同一个数据库的多个连接,因为它违反了一致性。您需要访问相同的开放变量来执行数据库操作,而不是每次都创建。
-
@SubashKharel 不正确。您可以有多个连接。这里的问题是连接完成后它们都没有关闭。
-
正是,当你不关闭前一个并新建并开始对数据库进行操作时,它更有可能发生。