1

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タイプの1列のテーブルにすぎません。

dbファイルがまったく更新されないことを除いて、すべてが正常に見えます。Selectクエリは完全に正常に機能するため、私には本当に混乱します。データベースのパスを確認しました。正しいパスを指しています。最初はファイルのアクセス許可が原因だと思いますが、誰もが読み取り/書き込みできるようにしたとしても、問題は同じです。

私は何時間もこの問題に悩まされており、適切な解決策を見つけることができませんでした。誰かがこれに光を当てることができますか?ありがとう!

4

1 に答える 1

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;    
}
于 2011-10-27T03:17:30.510 に答える