2016-10-07 1 views
1

У меня проблема с Sqlite в Swift. Каждый раз, когда я запускаю свое приложение на симуляторе и вставляю новую запись, после успешной вставки я не могу вставлять или обновлять, удалять любые записи, это похоже на замену базы данных на чтение. Но если я запустил свое приложение без вставки новой записи, то обновление, удаление заявлений полностью прекратится. Я открываю и закрываю соединение с базой данных каждый раз при выполнении любых операторов SQL. Вот моя вставка функции: функцияSQLite in Swift: невозможно вставить, обновить, удалить записи после вставки записи в базу данных

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

@Rob спасибо !. Я добавил «sqlite3_errmsg», и он возвращает: «база данных заблокирована». Кроме того, я создал класс только для базы данных, который содержит эти функции, есть еще два класса, наследуемых от класса базы данных, и использовать эти функции, поэтому я думаю, что лучше закрыть базу данных каждый раз при использовании этих функций. –

+0

@Rob спасибо. Как вы сказали, я только что выяснил, что инструкция SELECT еще не завершена. Я исправил его, и теперь он работает как шарм. Огромное спасибо!!! –

ответ

0

Пара мыслей:

  1. Если sqlite3_open терпит неудачу, вы должны проверить цифровой код возврата. Если другой вызов SQLite не удался, я бы предложил изучить результат sqlite3_errmsg. Используя их, вы можете диагностировать причину неудачи.

  2. Сделав это, вы сообщили нам, что сообщили, что «база данных заблокирована».
    Как правило, это результат попытки выполнить запрос, в то время как другой все еще выполняется. Я ничего здесь не вижу, но мне интересно, есть ли у вас какой-то другой код, который делает SELECT, для которого вы, возможно, пренебрегли финализацией/закрытием (или, возможно, вы находитесь в середине SELECT, а затем пытаетесь сделать один из эти операторы обновления).

    Я бы предложил разместить оператор журнала в базе данных connectDatabase и снова повсюду, где вы закрываете базу данных, и я уверен, вы найдете последовательность, в которой вы пытаетесь открыть базу данных, до того, как увидите закрытие предыдущего вызова.

    Независимо от того, эта «база данных заблокирована» была discussed extensively on Stack Overflow, поэтому см. Это для получения дополнительной информации.