База данных заблокирована в Sqlite
Я разрабатываю приложение для iPhone, когда я вставляю данные в базу данных, я получил "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while inserting data. 'database is locked''" Error.
Код:
- (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);
}
Пожалуйста, дайте мне решение для этого.
Большое спасибо...
Ответы
Ответ 1
Искать комментарий //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.
}
Ответ 2
вам нужно завершить составленные скомпилированные операторы, а затем закрыть базу данных, прежде чем открывать ее снова.
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
Ответ 3
Вышеуказанные ответы верны, однако есть способ, с которого база данных показывает ошибку блокировки, если мы работаем или отлаживаем на симуляторах.
Случай 1:
Здесь я объясняю сценарий, когда я вставляю данные в таблицу. И эта база данных обращается к любому браузеру базы данных и получает доступ к симулятору.
Теперь, когда вы работаете с приложением через симулятор, по мере сохранения данных в данных базы данных. Теперь, если вы используете любой браузер для доступа к данным из этой базы данных, и если вы запускаете любую команду обновления в своем браузере и пытаетесь обновить любую строку, она обновляет эту строку в таблице. (Теперь, когда мы пытаемся удалить что-либо из таблицы, оно всегда показывает сообщение о том, что разрешения браузера доступны только для чтения и т.д.).
Теперь зайдите на симулятор или снова запустите приложение
и когда вы пытаетесь вставить какие-либо данные в эту таблицу, всегда отображается ошибка "База данных заблокирована", потому что разрешения доступны только для чтения, и мы закалили эти разрешения. Теперь, если вы попытаетесь изменить команды, как указано в ответах, вы всегда будете печальны. Он всегда показывает ошибку базы данных заблокирован (как я пытался несколько раз, чтобы решить эту проблему, но каждый раз, когда я провалился).
Есть только способ удалить из этой ситуации: удалить приложение с вашего симулятора и переустановить его.
И избегайте обновления/вставки любой строки из браузера.
Другой ответ:
Случай 2:
Когда вы работаете над браузером sqlite и делаете из него какие-либо обновления, убедитесь, что вы сохранили все изменения, произошедшие.