0

こんにちは、アプリケーション デリゲートでデータベースの冗長性を削除する関数を作成しました。DB のエラーを見つけるために SQL ステートメントのネストを実行する必要があるため、正しくコーディングされているかどうかわかりません。

アプリケーションがシミュレーターで正常に動作し、デバイスでクラッシュしているため、どこが間違っているかを誰かが教えてくれますか?

finalize と sqlite3_close をどこに置くべきかさえわかりません。親切に助けて

 -(void) removeRedundancy2
    {
        NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        dbPathString = [[docPaths objectAtIndex:0] stringByAppendingPathComponent:@"turfnutritiontool_ver_99.db"];
        sqlite3_stmt *selectStmt;
        sqlite3_stmt *selectStmt1;
        BOOL isMyFileThere = [[NSFileManager defaultManager] fileExistsAtPath:dbPathString];

        if (isMyFileThere)
        {
            if (sqlite3_open([dbPathString UTF8String], &database1)==SQLITE_OK)
            {
                // TO REMOVE FROM from tnt_scenario_product when NO ProductID Found

                NSString *querySql2= [NSString stringWithFormat:@"SELECT productid from tnt_scenarioproduct"];
                const char* query_sql2 = [querySql2 UTF8String];

                if(sqlite3_prepare_v2(database1, query_sql2, -1, &selectStmt, NULL) == SQLITE_OK)
            {
                while (sqlite3_step(selectStmt) == SQLITE_ROW)
                {
                    int productid =  sqlite3_column_int(selectStmt, 0);
                    // NSLog(@"ProductId1 =%d",productid);

                    NSString *querySql21= [NSString stringWithFormat:@"SELECT productid from tnt_productcontent WHERE productid = %d",productid];
                    const char* query_sql21 = [querySql21 UTF8String];

                    if(sqlite3_prepare_v2(database1, query_sql21, -1, &selectStmt1, NULL) == SQLITE_OK)
                    {
                        if (sqlite3_step(selectStmt1) == SQLITE_ROW)
                        {
                            // DO NOTHING
                        }
                        else
                        {   // to delete scenario without product id
                            NSLog(@"Delete this Product from TPC 2 %d",productid);
                            NSString *querydelete2= [NSString stringWithFormat:@"DELETE from tnt_scenarioproduct WHERE productid = %d",productid];

                            const char* query_delete2 = [querydelete2 UTF8String];
                            char *error;
                            sqlite3_exec(database1, query_delete2, NULL, NULL, &error);
                            NSLog(@"error=%s ",error);
                            sqlite3_finalize(selectStmt1);
                        }
                    }
                    sqlite3_finalize(selectStmt1);
                    sqlite3_close(database1);

                }
                sqlite3_finalize(selectStmt);
            }
            sqlite3_close(database1);
        }
        sqlite3_close(database1);

    }
}
4

1 に答える 1

0

を呼び出した後sqlite3_open、その接続を 1 回だけ呼び出す必要があります。sqlite3_closeを呼び出した後sqlite3_prepare_v2、そのステートメントを 1 回だけ呼び出す必要があります。sqlite3_finalize

if (sqlite3_open([dbPathString UTF8String], &database1)==SQLITE_OK)
{
    ...
    if(sqlite3_prepare_v2(database1, query_sql21, -1, &selectStmt1, NULL) == SQLITE_OK)
    {
        ...
    }
    sqlite3_finalize(selectStmt);
    ....
}
sqlite3_close(database1);

さらに、2 つの異なるクエリに対して同じ変数 ( selectStmt) を再利用して、その有効期間に関する混乱を避けるべきです。

于 2013-03-21T15:25:56.973 に答える