在iPhone上锁定sqlite文件

时间:2010-09-13 23:31:19

标签: iphone sqlite

到目前为止,我的所有数据库访问都已读取,但现在我需要更新(并在此插入之后)

我在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(数据库); 关闭一切?

1 个答案:

答案 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);
}