4

sqliteではデフォルトで外部キーが無効になっているという事実に出くわしました。「on delete casdade」外部キーがあり、親テーブル レコードを削除しても子レコードは削除されません。さまざまな投稿は、接続ごとに「PRAGMAforeign_keys = ON;」を有効にする必要があることを示しています。では、FMDatabase のどこで有効にするのでしょうか? 各 SQL stmt の前にコマンドを実行する代わりに、何らかの設定を行うことをお勧めします。PS。FMDatabaseQueue を使用しています。

4

4 に答える 4

8

私はすぐにチェックしPRAGMA foreign_keys = ON;、5.1 シミュレーターと 5.1 iPod Touch の両方で問題なく動作しました。ccgus が示唆するように、データベース接続をキャッシュする必要があります。キューを使用する場合は、データベースを使用する必要があるたびに新しいキューが作成されないように、キューをキャッシュしてコードを再編成するだけです。あなたの現在のアプローチでは、実際には使用せずに毎回新しいキューを作成する場合、キューを持つ意味は何ですか?

質問に戻りますが、ご存知のように、外部キーはデフォルトでオフになっているため、最初に有効にする必要があります。私はなんとかそれを行うことができましたPRAGMA foreign_keys = ON;.ここに私が使用したテストコードのいくつかがあります:

//create database
NSString* dbPath = [(NSArray*)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
dbPath = [dbPath stringByAppendingPathComponent:@"test.db"];
db = [FMDatabase databaseWithPath:dbPath];
if ([db open]) {
    NSLog(@"Database %@ opened", dbPath);
    //check for foreign_key
    NSString* sql = @"PRAGMA foreign_keys";
    FMResultSet *rs = [db executeQuery:sql];
    int enabled;
    if ([rs next]) {
        enabled = [rs intForColumnIndex:0];
    }
    [rs close];
    if (!enabled) {
        // enable foreign_key
        sql = @"PRAGMA foreign_keys = ON;";
        [db executeUpdate:sql];
        // check if successful
        sql = @"PRAGMA foreign_keys";
        FMResultSet *rs = [db executeQuery:sql];
        if ([rs next]) {
            enabled = [rs intForColumnIndex:0];
        }
        [rs close];
    }
    // do your stuff here, or just cache the connection
} else {
    NSLog(@"Failed to open %@", dbPath);
}

かなり単純に見えますが、頭に浮かぶのはexecuteQueryの代わりにを使用したことだけですexecuteUpdate

于 2012-05-08T11:11:54.560 に答える
1

各ステートメントの前に実行する必要があるのはなぜですか? データベースを開き、プラグマを実行し、後で使用するために接続をキャッシュするだけです (とにかくこれを行う必要があります)。

于 2012-05-07T23:55:31.913 に答える