1

非常に複雑なクエリでテーブル 'Children' をクエリしているという奇妙なバグがあります。正常に動作しますが、何らかの理由で、データベースの更新からこの他のビューにバグが発生します。このデータベースにはステッカーが保管されていることがわかります。ステッカーを配布する簡単な方法の 1 つは、この管理ページにアクセスすることです。情報をうまく照会できますが、! テーブルを更新すると、嫌いで機能しません。しかし、コアView Controller内では奇妙で、そこでテーブルを更新してもバグはありません。この問題の原因にコードを絞り込みました。

-(void)leaderboardsystem
{  
    NSString *nexttargetsql = [NSString stringWithFormat:@"SELECT * FROM Children WHERE Completed > %d OR (Completed = %d AND Current_Stickers > %d) ORDER BY Completed ASC, Current_Stickers ASC LIMIT 1",completecount,completecount,stickercount]; //Queries table for the childs name and returns more data.
    NSString *behindyousql = [NSString stringWithFormat:@"SELECT * FROM Children WHERE Completed < %d OR (Completed = %d AND Current_Stickers < %d) ORDER BY Completed DESC, Current_Stickers DESC LIMIT 1",completecount,completecount,stickercount];

    nexttarget.text = [self leaderboardQuery:nexttargetsql];
    behindyou.text = [self leaderboardQuery:behindyousql];

    }


-(NSString*)leaderboardQuery:(NSString*)sql//does the querying
{
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(Childdb, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {
        while (sqlite3_step(statement)==SQLITE_ROW) {
            char *ffield1 = (char *) sqlite3_column_text(statement, 0);
            NSString *ffield1Str = [[NSString alloc]initWithUTF8String:ffield1];
            char *ffield2 = (char *) sqlite3_column_text(statement, 8);
            NSString *ffield2Str = [[NSString alloc]initWithUTF8String:ffield2];
            char *ffield3 = (char *) sqlite3_column_text(statement, 10);
            NSString *ffield3Str = [[NSString alloc]initWithUTF8String:ffield3];
            NSLog(@"Name:%@",ffield1Str);
            NSLog(@"this is completecount: %@", ffield2Str);
            NSLog(@"this is stickcount: %@",ffield3Str);
            return ffield1Str;
        }

    }
        return NULL;
}

メソッド Leaderboardsystem を呼び出すたびにこのバグが発生しますが、そうしないと問題なく動作します。面白いことに、正直に言うと少し驚きました。メインビューに接続されていないまったく別のView Controllerに影響を与えるので、私は驚いています。テーブル レイアウトは次のとおりです。

[self createTable:@"Children" withField1:@"Name" withField2:@"Password" withField3:@"House" withField4:@"Sticker Collection" withField5:@"Tickets Gathered" withField6:@"Tickets Removed" withField7:@"Last Ticket Scanned" withField8:@"Current Tickets" withField9:@"Completed" withField10:@"Complete" withField11:@"Current_Stickers"];

これは、リーダーボード システムをメイン ビューに含めると失敗するように見える更新コードです (これはまったく別のビュー コントローラーにあります)。

-(void)UpdateDatabase//update table, if value has been incremented
{
    NSString *sql = [NSString stringWithFormat:@"UPDATE Children SET 'Current Tickets' = %d, 'Tickets Removed' = %d, 'Tickets Gathered' = %d WHERE Name = '%@'",[self.currenttickets.text integerValue], [self.removedtickets.text integerValue], [self.totaltickets.text integerValue], name];
    [self updatetable:sql];
}

-(void)updatetable:(NSString*)sql
{
    char *err;
    if (sqlite3_exec(Childdb, [sql UTF8String], NULL, NULL, &err)!=SQLITE_OK) {
        sqlite3_close(Childdb);
        NSAssert(0, @"Could not update Table");
    } else {
        NSLog(@"Table updated");
    }
}

ここで説明を過負荷にしないように努めており、簡潔に保つようにしています。これ以上の情報が必要な場合はお知らせください。しかし、リーダーボード システムが問題を引き起こしていることを保証します。この問題を解決できたら、100 万人に感謝します。一日中取り組んでいます。:(

また、テーブルにレコードを追加する場所も邪魔されるため、更新コードが原因ではありません。そのリーダーボードクエリ、理由はわかりません:(

4

2 に答える 2

0

わかりました、まあ、私はこれをやりたくありませんでした。しかし、クエリを管理するメソッドを用意する代わりに、メソッド内で2回繰り返しましたが、うまくいきました! 何が問題だったのかわからない。誰も私を助けてくれなかったようですので、そのままにしておきましょう。

于 2013-02-27T21:13:21.063 に答える
0

に電話する必要がありますsqlite3_finalize(Childdb)。次のようになります。

-(NSString*)leaderboardQuery:(NSString*)sql//does the querying
{
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(Childdb, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {
        while (sqlite3_step(statement)==SQLITE_ROW) {
           ...
        }
    }
    sqlite3_finalize(Childdb);
    return NULL;
}

エラー処理がないため、これは非常に単純な例です。これについて説明しているドキュメントは次のとおりです (ここにあります)。

*ppStmt は、sqlite3_step() を使用して実行できるコンパイル済みの準備済みステートメントを指しているままになります。エラーが発生した場合、*ppStmt は NULL に設定されます。入力テキストに SQL が含まれていない場合 (入力が空の文字列またはコメントの場合)、*ppStmt は NULL に設定されます。呼び出し元のプロシージャは、コンパイル済みの SQL ステートメントの処理が終了した後、sqlite3_finalize() を使用して、コンパイル済みの SQL ステートメントを削除する責任があります。ppStmt は NULL であってはなりません。

このコード例が役立つかもしれません: https://github.com/ccgus/fmdb/blob/master/src/FMDatabase.m#L519

于 2013-02-27T23:25:08.723 に答える