FMDB - 无法从 Cocoa 修改数据库

Posted

技术标签:

【中文标题】FMDB - 无法从 Cocoa 修改数据库【英文标题】:FMDB - Failed to modify DB from Cocoa 【发布时间】:2011-10-27 02:17:37 【问题描述】:

我正在开发一个使用 FMDB 与本地 SQLite 数据库对话的 Cocoa 应用程序。我遇到了一个问题,我无法在 DB 上执行任何插入或更新操作。选择查询运行得很好,所以我假设我的数据库连接设置是正确的。

我的代码结构基本上是这样的:

FMDatabase* db=[FMDatabase databaseWithPath:[[NSBundle mainBundle] pathForResource:@"DBName" ofType:@"sqlite"]];

if(![db open])

  NSLog(@"Could not open db.");


db.traceExecution=YES;
[db beginTransation];
[db ExecuteUpdate:"INSERT INTO test (title) VALUES(?)", [NSNumber numberWithInt]:2],nil];
[db commit];
[db close];

执行过程中没有抛出异常或警告,关于 db.traceExecution 的控制台输出如下:

<FMDatabase: 0x100511fd0> executeUpdate: BEGIN EXCLUSIVE TRANSACTION;
<FMDatabase: 0x100511fd0> executeUpdate: INSERT INTO test (title) VALUES(?);
obj: 2
<FMDatabase: 0x100511fd0> executeUpdate: COMMIT TRANSACTION;

测试数据库只是一个 INT 类型的单列表。

一切看起来都很好,只是 db 文件根本没有更新。这让我很困惑,因为 Select 查询工作得非常好。我检查了数据库的路径,它指向正确的路径。首先我怀疑它是由文件权限引起的,但是即使我允许每个人都能够读/写,问题仍然存在。

我已经被这个问题困扰了好几个小时,找不到合适的解决方案。任何人都可以对此有所了解吗?谢谢!

【问题讨论】:

布莱恩是对的。遇到相同问题的人的解决方案:将您的 db 文件复制到项目文件夹之外。就我而言,进入 ~/Documents/ 文件夹解决了我的问题。 helpful link 是的,我做到了。抱歉,我忘记将您的答案标记为已接受。再次感谢! 【参考方案1】:

包中的数据库是只读的。如果您定义的目标文件夹中不存在该文件,则应将其从捆绑包复制到库或文档文件夹,然后连接到该文件夹​​。这意味着它将在第一次使用该路径时复制。

这是一个通过将数据库从包中复制到目标来“准备”数据库的函数。它将它复制到图书馆(从我的 ios 应用程序),但你可以复制到任何你想要的地方。就我而言,它是contacts.db。

我从 ensureOpened 调用了这个方法。

- (BOOL)ensureDatabasePrepared: (NSError **)error

    // already prepared
    if ((_dbPath != nil) &&
        ([[NSFileManager defaultManager] fileExistsAtPath:_dbPath]))
    
        return YES;
    

    // db in main bundle - cant edit.  copy to library if !exist
    NSString *dbTemplatePath = [[NSBundle mainBundle] pathForResource:@"contacts" ofType:@"db"];
    NSLog(@"%@", dbTemplatePath);

    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    _dbPath = [libraryPath stringByAppendingPathComponent:@"contacts.db"];

    NSLog(@"dbPath: %@", _dbPath);

    // copy db from template to library
    if (![[NSFileManager defaultManager] fileExistsAtPath:_dbPath])
    
        NSLog(@"db not exists");
        NSError *error = nil;
        if (![[NSFileManager defaultManager] copyItemAtPath:dbTemplatePath toPath:_dbPath error:&error])
        
            return NO;
        

        NSLog(@"copied");
        

    return YES;    

【讨论】:

感谢您的建议。我试过你说的方法。在我的情况下,它总是返回“//已经准备好”。所以它不会到达将db文件复制到库的下一步。 刚刚想通了。 link。没错,我没有对 NSBundle 中的 db 文件的写访问权限。但是,至少在我的情况下,将文件复制到库路径并不能解决权限问题。将其复制到 ~/Documents/ 文件夹解决了我的问题。

以上是关于FMDB - 无法从 Cocoa 修改数据库的主要内容,如果未能解决你的问题,请参考以下文章

FMDB:错误 14,无法打开数据库文件

FMDB,sqlite json-string 成字典?

使用 fmdb 无法更新 blob 类型数据

从 cocoa 中修改 .webarchive 并再次写出

iOS FMDB 无法更新二进制数据的问题

无法使用 swift 3 在 FMDB 中执行更新