我在Swift中遇到了Sqlite的问题。每次我在模拟器上运行我的应用程序并插入新记录,然后插入成功后,我无法插入或更新,删除任何记录,它就像数据库更改为只读。但是,如果我在没有插入新记录的情况下运行我的应用程序,那么更新,删除语句完全正常。 每次执行任何SQL语句时,我都会打开然后关闭与数据库的连接。 这是我的插入功能:
func insertJobToDatabase(label: String, startTime: NSDate, finishTime: NSDate, startDay: NSDate, finishDay: NSDate, color: String){
let db = connectDatabase("TimeTable.sqlite")
// Set date formatter
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"
//Insert string of interting new job
let insertStatementString = "INSERT INTO Jobs VALUES (\"\(label)\",'\(dateFormatter.stringFromDate(startTime))','\(dateFormatter.stringFromDate(finishTime))','\(dateFormatter.stringFromDate(startDay))','\(dateFormatter.stringFromDate(finishDay))',\"\(color)\", \(Int(self.getMaxIdOfTable(db)+1)));"
//compile Insert string
var insertStatement: COpaquePointer = nil
if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
//Execute Insert string
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)
if sqlite3_close_v2(db) == SQLITE_OK{
print("closed")
}
}
更新功能:
func updateDatabase(updateStatementString: String){
let db = connectDatabase("TimeTable.sqlite")
var updateStatement: COpaquePointer = nil
if sqlite3_prepare(db, updateStatementString, -1, &updateStatement, nil) == SQLITE_OK{
if sqlite3_step(updateStatement) == SQLITE_DONE{
print("Successfully update row.")
}
else{
print("Could not update row.")
}
}
else{
print("UPDATE statement could not be prepared")
}
sqlite3_finalize(updateStatement)
if sqlite3_close_v2(db) == SQLITE_OK{
print("closed")
}
}
删除功能:
func deleteInDatabase(id: Int){
let db = connectDatabase("TimeTable.sqlite")
let deleteStatementString = "DELETE FROM Jobs WHERE id = \(id)"
var deleteStatement: COpaquePointer = nil
if sqlite3_prepare(db, deleteStatementString, -1, &deleteStatement, nil) == SQLITE_OK{
if sqlite3_step(deleteStatement) == SQLITE_DONE{
print("Successfully deleted row.")
}
else{
print("Could not delete row.")
}
}
else{
print("DELETE statement could not be prepared")
}
sqlite3_finalize(deleteStatement)
if sqlite3_close_v2(db) == SQLITE_OK{
print("closed")
}
}
connectDatabase函数:
func connectDatabase(fileName: String) -> COpaquePointer {
var db: COpaquePointer = nil
//Searching for path of database
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let fileURL = documentsURL.URLByAppendingPathComponent(fileName)
let dbPath: String = fileURL!.path!
let fileManager = NSFileManager.defaultManager()
if !fileManager.fileExistsAtPath(dbPath){ //If database not exist then...
let documentURL = NSBundle.mainBundle().resourceURL
let fromPath = documentURL!.URLByAppendingPathComponent(fileName) //Get database path from projects location
var error: NSError?
do {
try fileManager.copyItemAtPath(fromPath!.path!, toPath: dbPath) //Try to copy database from projects location to applications documents location
} catch let error1 as NSError{
error = error1
}
let alert: UIAlertView = UIAlertView()
if(error != nil){
alert.title = "Error Occured"
alert.message = error?.localizedDescription //If database is not exist in projects location then pop out error alert
}
else {
alert.title = "Successfully Copy" //Notify by an alert if copy successfully
alert.message = "Your database copy successfully"
if sqlite3_open(dbPath, &db) == SQLITE_OK {
print("Successfully opened connection to database") //Open database just copied
} else {
print("Unable to open database")
}
}
alert.delegate = nil
alert.addButtonWithTitle("Ok")
alert.show()
}
else{
print("Database already exist in \(dbPath)") //Notify by an alert if there's already a database in applications documents location
if sqlite3_open(dbPath, &db) == SQLITE_OK {
print("Successfully opened connection to database") //Open database without copy
} else {
print("Unable to open database")
}
}
return db
}
我确定我的应用程序连接到数据库并且更新,删除语句没有任何问题,因为我仍然可以更新,如果尚未插入任何记录则删除记录。
答案 0 :(得分:0)
有几点想法:
如果sqlite3_open
失败,您应该检查数字返回码。如果另一个SQLite调用失败,我建议检查sqlite3_errmsg
的结果。使用这些,您可以诊断它失败的原因。
完成后,您告知我们已报告"数据库被锁定" 这通常是尝试执行查询而另一个仍在进行中的结果。我在这里看不到任何东西,但是我想知道你是否有其他代码执行SELECT,你可能忽略了最终/关闭(或者你可能在SELECT的中间然后尝试做其中一个更新语句。)
我建议在connectDatabase中添加一个日志语句,并在关闭数据库的任何地方再次,我打赌你会在看到先前调用结束之前找到一些尝试打开数据库的序列
无论如何,这个"数据库已被锁定"已经discussed extensively on Stack Overflow,所以请查看以获取更多信息。