2016-10-07 2 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'를 추가하고 리턴한다 : '데이터베이스가 잠겨있다'. 또한이 함수가 포함 된 데이터베이스 용 클래스를 만들었습니다. 데이터베이스 클래스로부터 상속받은 두 개의 클래스가 있고이 함수를 사용하기 때문에 이러한 함수를 사용할 때마다 데이터베이스를 닫으면 더 좋을 것이라고 생각합니다. –

+0

@Rob 감사합니다. 당신이 말했듯이, 나는 단지 SELECT 문이 아직 완성되지 않았 음을 알았습니다. 나는 그것을 고쳤고 지금은 매력처럼 작동한다. 정말 고맙습니다!!! –

답변

0

생각을 몇 :

sqlite3_open이 실패하면
  1. , 당신은 숫자 반환 코드를 검사해야한다. 다른 SQLite 호출이 실패하면 sqlite3_errmsg의 결과를 검토하는 것이 좋습니다. 그것들을 사용하여 실패한 이유를 진단 할 수 있습니다.

  2. 이 작업을 마치면 "데이터베이스가 잠겼습니다."라는 메시지가 나타났습니다.
    일반적으로 다른 쿼리가 아직 진행 중일 때 쿼리를 수행 한 결과입니다. 여기에 아무 것도 보이지 않지만 SELECT를 수행하는 다른 코드가 있는지 궁금해합니다.이 코드는 종료/닫기를 소홀히했을 수도 있습니다 (또는 SELECT의 중간에있을 수도 있고 다음 중 하나를 시도 할 수도 있습니다). 이 업데이트 문).

    나는 connectDatabase에 로그 문을 넣고 다시 데이터베이스를 닫는 것이 좋습니다. 그러면 이전 호출 닫기를보기 전에 데이터베이스를 여는 순서를 찾을 수 있습니다.

    이 "데이터베이스 잠김"은 discussed extensively on Stack Overflow 이었으므로 자세한 내용을 참조하십시오.

관련 문제