iPhone sqlite3锁定,只能读,不能写

发布于 2024-08-10 03:48:47 字数 1622 浏览 8 评论 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;
    }

So I have been working on this project for a short while now. I have no problems with reading data from the DB, and formatting it into UITableViews and what not. But now I am wanting also to write to the DB as well. The problem is I keep getting a "Database is Locked" error from sqlite. After messing around with the original version I had the face-palm moment by realizing my database was in the bundle and therefore not writable. So I relocated the DB to the Apps Documents folder, which is writeable. But now I still get the same "Database is Locked" sql error. I only open and close the DB when necessary. And as far as I can tell, I don't leave it open anywhere. Below is the code where I am wanting to do updates. Any thoughts?

    - (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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不喜欢何必死缠烂打 2024-08-17 03:48:47

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

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

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

Open the database once at the start of your app, then close it in applicationWillTerminate of the AppDelegate.

After every exec you will want to do a reset to clear the connection state.

Take a look at the SQLiteBooks sample app, it is coded this way.

好菇凉咱不稀罕他 2024-08-17 03:48:47

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

有关详细信息,请参阅

您将在哪里放置iPhone 应用程序中的 SQLite 数据库文件?

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

How do you move the DB to the documents folder from the bundle? You need to check that it is there, and if not copy it. I get the feeling that either you have copied it some other way, but retained a read-only attribute, or more likely, you are still referencing the original in the bundle.

For details see

Where would you place your SQLite database file in an iPhone app?

or as joshperry says, the SQLiteBooks sample has all the code you need.

十级心震 2024-08-17 03:48:47

你如何获得loanBookTo?如果数据库已打开,然后您调用loanBookTo,它可能不会抛出打开错误,但数据库会保留您来时的状态。

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

How are you getting to loanBookTo? If the database is open and then you call loanBookTo, it may not throw an error of the open, however the database is holding the state from where you came.

Also, at times, the database retains the locked state upon closing and exiting the application, so you could be 'inheriting' a locked state from your previous failures. Deleting the app from the simulator should give you a clean copy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文