0

所以我在这个项目上工作了一段时间。我从数据库读取数据并将其格式化为 UITableViews 没有问题。但现在我也想写入数据库。问题是我不断从 sqlite 收到“数据库已锁定”错误。在弄乱了原始版本之后,我意识到我的数据库在捆绑包中,因此不可写,从而获得了面对面的时刻。所以我将数据库重新定位到可写的 Apps Documents 文件夹。但现在我仍然得到相同的“数据库已锁定”sql 错误。我只在必要时打开和关闭数据库。据我所知,我不会让它在任何地方打开。下面是我想要更新的代码。有什么想法吗?

    - (BOOL) loanBookTo:(NSString *)newborrower{
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"books.sqlite"];   

        if([[NSFileManager defaultManager] fileExistsAtPath:path]){
            NSLog(@"File Exists at: %@", path);
        }


        if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {  
            NSString *mySQL = @"UPDATE BOOKS SET LOANED = 1, BORROWER = \"<BORROWER>\" where ISBN = \"<ISBN>\"";
            mySQL = [mySQL stringByReplacingOccurrencesOfString:@"<ISBN>" withString:self.isbn];
            mySQL = [mySQL stringByReplacingOccurrencesOfString:@"<BORROWER>" withString:newborrower];
            const char *sql = [mySQL UTF8String];
            char* errmsg;
            sqlite3_exec(database, sql, NULL, NULL, &errmsg);

            // Q. Database is locked. Why?
            // A. Because it is in the Bundle and is ReadOnly.
            //    Need to write a copy to the Doc folder.

            // Database is Locked error gets spit out here. 
            printf(errmsg);
            sqlite3_close(database);
        }   
        return NO;
    }
4

3 回答 3

0

在应用程序启动时打开数据库一次,然后在 AppDelegate 的 applicationWillTerminate 中将其关闭。

每次执行后,您都需要进行重置以清除连接状态。

看一下 SQLiteBooks 示例应用程序,它是这样编码的。

于 2009-10-31T07:41:53.863 回答
0

如何将 DB 从捆绑包中移至文档文件夹?您需要检查它是否存在,如果没有则复制它。我觉得您要么以其他方式复制了它,但保留了只读属性,或者更有可能的是,您仍在引用捆绑包中的原始属性。

详情见

您会将 SQLite 数据库文件放在 iPhone 应用程序的什么位置?

或者正如 joshperry 所说,SQLiteBooks 示例包含您需要的所有代码。

于 2009-10-31T13:33:17.253 回答
0

你怎么去loanBookTo?如果数据库是打开的,然后你调用了loanBookTo,它可能不会抛出打开的错误,但是数据库保持着你来的状态。

此外,有时,数据库在关闭和退出应用程序时会保留锁定状态,因此您可能会从以前的失败中“继承”锁定状态。从模拟器中删除应用程序应该会给你一个干净的副本。

于 2012-05-15T14:11:21.757 回答