到目前为止,我的所有数据库访问都已读取,但现在我需要更新(并在此插入之后)
我在app目录中有一个包含'shows'的数据库(只读),这对我来说没关系(我不想把它复制到文件夹,因为它相当大,我不需要改变其中的东西。
但我希望用户选择一些节目作为他的最爱。因此,我在documents文件夹中创建了一个带有'favorite_shows'表的数据库。它包含4个字段: ID(原始键) show_id is_favorite 备注(目前尚未使用)
用户可以切换'is_favorite'状态ONCE,之后我在尝试更新时遇到错误:
SQLITE_BUSY 5 / *数据库文件被锁定* /
这是我的代码:
if (sqlite3_open([databasePath UTF8String],&database) == SQLITE_OK){
sqlStatement = "select * from favorite_shows WHERE (show_id = ?)";
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, self.ID);
// search for a show
if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// if we can find one, toggle the status
favID = sqlite3_column_int(compiledStatement, 0); // we need the primary key to update it
isFav = (sqlite3_column_int(compiledStatement, 2) == 1); // let's store the favorite status
sqlStatement = "update favorite_shows SET is_favorite = ? WHERE (ID = ?)";
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, !isFav );
sqlite3_bind_int(compiledStatement, 2, favID);
int error = sqlite3_step(compiledStatement);
if (SQLITE_DONE != error) {
NSLog(@"error while updating favorite status");
}
}
}
//else : no records found indicating that this show hasn't been a favorite yet, so insert one as favorite
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
第二次锁定的原因是什么?除此之外是否还有其他指示:
sqlite3_finalize(compiledStatement);
sqlite3_close(数据库);
关闭一切?
答案 0 :(得分:8)
编辑:
BUSY是重新使用compiledStatement
而不删除先前编译的语句的结果。您需要使用finalize和close函数正确释放资源。
请参阅此处的文档。 http://sqlite.org/c3ref/stmt.html
const char * select = "select * from favorite_shows WHERE (show_id = ?)";
const char * update = "update favorite_shows SET is_favorite = ? WHERE (ID = ?)";
sqlite3_stmt *selectStmt;
sqlite3_stmt *updateStmt;
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
if(sqlite3_prepare_v2(database, select, -1, &selectStmt, NULL) == SQLITE_OK) {
sqlite3_bind_int(selectStmt, 1, self.ID);
// search for a show
if(sqlite3_step(selectStmt) == SQLITE_ROW) {
// if we can find one, toggle the status
favID = sqlite3_column_int(selectStmt, 0); // we need the primary key to update it
isFav = (sqlite3_column_int(selectStmt, 2) == 1) ? 0 : 1; // Flip is_favorite value
sqlite3_finalize(selectStmt); // Delete the statement OR create a new one
if(sqlite3_prepare_v2(database, update, -1, &updateStmt, NULL) == SQLITE_OK) {
sqlite3_bind_int(updateStmt, 1, isFav );
sqlite3_bind_int(updateStmt, 2, favID);
int error = sqlite3_step(updateStmt);
if (SQLITE_DONE != error) {
NSLog(@"error while updating favorite status");
} else {
sqlite3_finalize(updateStmt);
}
}
} //else : no records found indicating that this show hasn't been a favorite yet, so insert one as favorite
}
sqlite3_close(database);
}