objective-c - FMDB - 无法从 Cocoa 修改数据库

标签 objective-c cocoa fmdb

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

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

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 类型的单列表。

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

我已经被这个问题困扰了好几个小时,但找不到合适的解决方案。有人能解释一下吗?谢谢!

最佳答案

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

这是一个通过将数据库从包中复制到目标来“准备”数据库的函数。它将它复制到库(从我的 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;    
}

关于objective-c - FMDB - 无法从 Cocoa 修改数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7911053/

相关文章:

objective-c - 初始化方法中的 [self release]、[self dealloc] 或 [super dealloc]?

ios - 如何在 iOS 应用程序中连接 FMDB 中两个不同数据库的两个表

ios - objective-c 中的 Sqlite3 数据库 [需要建议]

ios - viewDidLoad 中的方法顺序

iphone - 核心数据: Editing many attributes laggy performance

iOS 更改表格 View 中的特定单元格

objective-c - NSTextField:integerValue 行为不一致

swift - 如何使用 Cocoa 在 Swift 中打开 macOS 中的另一个窗口

ios - UILabel - 设置旋转框架

objective-c - 使用 FMDB 从 sqlite DB 创建字典数组