0

嗨,我在我的应用程序委托中创建了一个函数来删除我的数据库的冗余,我不确定我的编码是否正确,因为我必须执行 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,您必须只调用sqlite3_close一次该连接。在调用之后sqlite3_prepare_v2,您必须只调用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);

此外,您不应selectStmt为两个不同的查询重复使用相同的变量 ( ),以防止混淆其生命周期。

于 2013-03-21T15:25:56.973 回答