2016-10-07 7 views
1

SwiftのSqliteに問題があります。私はシミュレータ上で私のアプリケーションを実行し、新しいレコードを挿入するたびに、正常に挿入した後、私は挿入や更新、レコードを削除することはできません、それはデータベースのように読み取り専用に変更。しかし、私は新しいレコードを挿入せずに私のアプリを実行し、更新、削除ステートメントは完全に正常に動作します。 SQL文を実行するたびに、データベースへの接続を開いて閉じます。SwiftのSQLite:レコードを挿入、更新、削除することができません。

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'を追加して戻ります: 'データベースはロックされています'。 さらに、これらの関数を含むデータベース用のクラスを作成しました。データベースクラスから継承した2つのクラスがあり、これらの関数を使用しています。 –

+0

@Robありがとうございました。あなたが言ったように、私はちょうどSELECTステートメントがまだファイナライズされていないことを発見しました。私はそれを修正し、今は魅力のように動作します。どうもありがとうございます!!! –

答えて

0

思考のカップル:

  1. sqlite3_openに失敗した場合は、数値のリターン・コードを調べる必要があります。別のSQLite呼び出しが失敗した場合は、sqlite3_errmsgの結果を調べることをお勧めします。これらを使用すると、なぜ失敗したのかを診断できます。

  2. これを実行したら、「データベースはロックされています」と報告されました。
    これは一般に、別のものがまだ進行中の間にクエリを実行しようとした結果です。私はここには何も表示されませんが、あなたはあなたが終わり/終わりを怠っているかもしれないSELECTを行う他のコードをいくつか持っているのだろうか(あるいはおそらくあなたはSELECTの真ん中にいて、これらの更新ステートメント)。

    私は、connectDatabaseにログステートメントを入れて、どこでもデータベースを閉じることをお勧めします。以前の呼び出しの終了を見る前に、データベースを開こうとするシーケンスを見つけることができます。

    この「データベースがロックされています」はdiscussed extensively on Stack Overflowでしたので、詳細はこちらを参照してください。

関連する問題