2011-04-14 17 views
12

में लॉक हो गया है मैं एक iPhone अनुप्रयोग के विकास कर रहा हूँ, जब मैं डेटाबेस के लिए डेटा सम्मिलित मैं "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while inserting data. 'database is locked''" Error. मिला कोड है:डेटाबेस SQLite

- (NSString *) getDBPath {   
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); 
     NSString *documentsDir = [paths objectAtIndex:0]; 
     return [documentsDir stringByAppendingPathComponent:@"Halal.sqlite"]; 
} 

+ (void) finalizeStatements { 

      if (database) sqlite3_close(database); 
      if (deleteStmt) sqlite3_finalize(deleteStmt); 
      if (addStmt) sqlite3_finalize(addStmt); 
      if (detailStmt) sqlite3_finalize(detailStmt); 
      if (updateStmt) sqlite3_finalize(updateStmt); 
} 

- (void) gettingData:(NSString *)dbPath { 

      NSLog(@"Data base path is %@",dbPath); 
      if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) 
      { 
       const char *sql = "select * from Product"; 
       sqlite3_stmt *selectstmt; 
       if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) 
       { 
        while(sqlite3_step(selectstmt) == SQLITE_ROW) 
        { 
     [membersInfoDict setValue:[NSString stringWithUTF8String:(char*)sqlite3_column_text(selectstmt, 0)] forKey:@"ProductName"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)] forKey:@"ProductBarcode"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)] forKey:@"ProductImage"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] forKey:@"ProductIngredients"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)] forKey:@"ProductStatus"]; 


         if(membersInfoDict) 
         { 
          [membersInfoArray addObject:membersInfoDict]; 
          membersInfoDict = nil; 
         // NSLog(@"Entered and return"); 
          return; 
         } 
        } 
       }    
      } 

      else 
       sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 

} 


- (void) addRecord:(NSMutableDictionary *)recordDict 
{ 
      if (sqlite3_close(database)) 
      { 
       NSLog(@"Closed"); 
       NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES); 
       NSString *documentsDir = [paths objectAtIndex:0]; 

       [self gettingData:[documentsDir stringByAppendingPathComponent:@"Halal.sqlite"]];     
      } 
      else { 
       NSLog(@"Not Closed"); 
      }    
      if(addStmt == nil) { 
       const char *sql = "insert into Product(ProductName, ProductBarcode , ProductImage,ProductIngredients,ProductStatus) Values(?,?,?,?,?)"; 
       if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) 
        NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 
      } 

      sqlite3_bind_text(addStmt, 1, [[recordDict objectForKey:@"ProductName"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 2, [[recordDict objectForKey:@"ProductBarcode"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 3, [[recordDict objectForKey:@"ProductImage"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 4, [[recordDict objectForKey:@"ProductIngredients"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 5, [[recordDict objectForKey:@"ProductStatus"] UTF8String], -1, SQLITE_TRANSIENT); 


      if(SQLITE_DONE != sqlite3_step(addStmt)) 
       NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
      else 
      //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid 
       rowID = sqlite3_last_insert_rowid(database); 
      NSLog(@"last inserted rowId = %d",rowID); 

      //Reset the add statement. 
      sqlite3_reset(addStmt); 
      //sqlite3_commit_hook(); 
      //sqlite3_commit_hook(addStmt,[NSString stringWithFormat:@"%d",rowID],database); 

} 

मुझे इस के लिए समाधान दे। बहुत बहुत धन्यवाद ...

+0

जहां आप ["डेटाबेस" sqlite3 * खोल रहे हैं और क्या कोई अन्य क्वेरी है जिसका आपने उपयोग किया है और यह अभी भी इसे खुला रख रहा है? – Ravin

+0

विवरण प्रदर्शित करते समय मैं डेटाबेस खोल रहा हूं – Anand

उत्तर

18

खोजें टिप्पणी //ADD THIS LINE TO YOUR CODE में तुम्हारा की विधि संशोधित निम्नलिखित।

- (void) gettingData:(NSString *)dbPath { 
    NSLog(@"Data base path is %@",dbPath); 
    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) 
    { 
     const char *sql = "select * from Product"; 
     sqlite3_stmt *selectstmt; 
     if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) 
     { 
      while(sqlite3_step(selectstmt) == SQLITE_ROW) 
      { 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char*)sqlite3_column_text(selectstmt, 0)] forKey:@"ProductName"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)] forKey:@"ProductBarcode"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)] forKey:@"ProductImage"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] forKey:@"ProductIngredients"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)] forKey:@"ProductStatus"]; 

       if(membersInfoDict) 
       { 
        [membersInfoArray addObject:membersInfoDict]; 
        membersInfoDict = nil; 
        // NSLog(@"Entered and return"); 
        sqlite3_close(database); 
        return; 
       } 
      } 
     } 
     //ADD THIS LINE TO YOUR CODE 
     sqlite3_finalize(selectstmt); 
    }   
    else 
     sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 
} 
+1

यदि (सदस्योंInfoDict) में आप डेटाबेस को जारी किए बिना वापस लौट रहे हैं। आप वहां एक sqlite3_close शामिल होंगे। – Vincent

+0

@ विन्सेंट धन्यवाद विन्सेंट – rptwsthi

+0

@ विन्सेन्ट को जब भी आप इसे एक्सेस करते हैं तो डीबी को बंद कर देना चाहिए? इसके अलावा, मैं डीबी खोलने के लिए एक विधि [स्वयं openDB] का उपयोग करता हूं। क्या इससे कोई फर्क पड़ता है कि मैं कार्यक्षमता को अलग करता हूं या मुझे एक ही स्थान पर हर चीज करना चाहिए। ऐसा लगता है कि इससे कोई फर्क नहीं पड़ता। – SonOfSeuss

9

आपको संकलित बयान को अंतिम रूप देने और फिर इसे खोलने से पहले डेटाबेस को बंद करने की आवश्यकता है।

sqlite3_finalize(compiledStatement); 
sqlite3_close(database); 
4

ऊपर उत्तर सही हैं, लेकिन वहाँ जिनमें से डेटाबेस शो त्रुटि से एक तरीका है, बंद कर दिया है कि अगर हम सिमुलेटर पर काम कर रहा है या डिबगिंग कर रहे हैं।

केस 1:

यहाँ मैं जब मैं एक तालिका में डेटा सम्मिलित एक परिदृश्य समझा रहा हूँ। और वह डेटाबेस किसी भी डेटाबेस ब्राउज़र और सिम्युलेटर से एक्सेस कर रहा है।

अब जब आप सिम्युलेटर के माध्यम से ऐप पर काम कर रहे हैं, तो आपने डेटाबेस डेटा में डेटा सहेजा है। अब यदि आप उस डेटाबेस से डेटा तक पहुंचने के लिए किसी भी ब्राउज़र का उपयोग कर रहे हैं और यदि आप अपने ब्राउज़र में किसी भी अपडेट कमांड को फायर करते हैं और किसी भी पंक्ति को अपडेट करने का प्रयास करते हैं तो यह उस पंक्ति को उस तालिका में अपडेट करता है। (अब जब हम टेबल से कुछ भी हटाने की कोशिश करते हैं तो यह हमेशा एक संदेश दिखाता है कि ब्राउज़र में केवल पढ़ने के लिए अनुमतियां दी जाती हैं)।

अब सिम्युलेटर पर आएं या यदि आप एप को फिर से चलाते हैं और जब आप उस तालिका में कोई भी डेटा डालने का प्रयास करते हैं, तो यह हमेशा त्रुटि दिखाता है 'डेटाबेस लॉक हो जाता है' क्योंकि अनुमति केवल पढ़ने के लिए होती है और हमने उन लोगों को कम किया अनुमतियाँ। अब यदि आप उत्तर में उल्लिखित आदेशों को बदलने का प्रयास करते हैं तो आपको हमेशा उदासी मिलेगी। यह हमेशा दिखाता है कि डेटाबेस की एक त्रुटि लॉक है (जैसा कि मैंने इसे हल करने के लिए कुछ बार कोशिश की लेकिन हर बार जब मैं असफल रहा)।

उस स्थिति से निकालने का केवल एक तरीका है: अपने सिम्युलेटर से ऐप हटाएं और इसे पुनः इंस्टॉल करें। और ब्राउज़र से किसी भी पंक्ति को अद्यतन/सम्मिलित करने से बचें।

एक और जवाब है: केस 2:

आप SQLite ब्राउज़र पर काम कर रहा है और इसमें कोई भी अद्यतनीकरण कर रहे हैं, सुनिश्चित करें कि आप अपने सभी परिवर्तन अन्य बुद्धिमान बंद कर दिया हालत होता बचाया है बनाते हैं।

संबंधित मुद्दे