IOS Sqlite3 Delete Query Not Deleting Row

iosiphoneobjective csqlite

I am using this code to delete a row from the database for my ipad application,

-(BOOL) removeSegmentWithSegmentId:(NSInteger)sId
{
    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];

    sqlite3_stmt *statement;

    NSString *removeKeyword =[NSString stringWithFormat:@"DELETE FROM segment WHERE segment.segment_id = %d",sId];
    const char *query = [removeKeyword UTF8String];
    NSLog(@"%@",removeKeyword);

    //if(sqlite3_prepare_v2(appDelegate->globalConnection,[removeKeyword UTF8String] , -1, &statement, NULL) == SQLITE_OK)
    if(sqlite3_prepare_v2(appDelegate->globalConnection,query , -1, &statement, NULL) == SQLITE_OK)
    {
        if(sqlite3_step(statement) == SQLITE_DONE) {
            sqlite3_finalize(statement);
            return YES;
        }
    }
    return NO;
}

but it is not working, can anyone guide me please?

Best Answer

Is your method returning YES?

A couple of things:

  • Always log sqlite3_errmsg on any failures
  • Right now, you're only doing sqlite3_finalize is sqlite3_step returns SQLITE_DONE, whereas you really should be doing it whenever you successfully did sqlite3_prepare_v2

So, I might suggest, at a minimum:

-(BOOL) removeSegmentWithSegmentId:(NSInteger)sId
{
    BOOL success = NO;

    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];

    sqlite3_stmt *statement;

    NSString *removeKeyword = [NSString stringWithFormat:@"DELETE FROM segment WHERE segment.segment_id = %d",sId];

    if (sqlite3_prepare_v2(appDelegate->globalConnection, [removeKeyword UTF8String], -1, &statement, NULL) == SQLITE_OK)
    {
        if(sqlite3_step(statement) == SQLITE_DONE) 
        {
            success = YES;
        }
        else
        {
            NSLog(@"%s: step not ok: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
        }
        sqlite3_finalize(statement);
    }
    else
    {
        NSLog(@"%s: prepare failure: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
    }

    return success;
}

Assuming this method was always returning YES, if you're not seeing records deleted, it must be that it's not finding a record to delete. (That is not considered a SQLite failure. The SQL was successfully executed, but the WHERE clause couldn't be satisfied.) You can verify this by defining the following method:

- (NSInteger)countSegmentWithSegmentId:(NSInteger)sId
{
    NSInteger count = 0;

    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];

    sqlite3_stmt *statement;

    NSString *sql = [NSString stringWithFormat:@"SELECT segment_id FROM segment WHERE segment.segment_id = %d", sId];

    if (sqlite3_prepare_v2(appDelegate->globalConnection, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)
    {
        while ((rc = sqlite3_step(statement)) == SQLITE_ROW)
            count++;

        sqlite3_finalize(statement);
    }
    else
    {
        NSLog(@"%s: prepare failure: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
        return -1;
    }

    return count;
}

And then put the diagnostic message in removeSegmentWithSegmentId:

- (BOOL)removeSegmentWithSegmentId:(NSInteger)sId
{
    BOOL success = NO;
    NSInteger count = [self countSegmentWithSegmentId:sId];

    NSLog(@"%s there are %d records with segment_id of %d", __FUNCTION__, count, sId);

    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];

    sqlite3_stmt *statement;

    NSString *removeKeyword = [NSString stringWithFormat:@"DELETE FROM segment WHERE segment.segment_id = %d",sId];

    if (sqlite3_prepare_v2(appDelegate->globalConnection, [removeKeyword UTF8String], -1, &statement, NULL) == SQLITE_OK)
    {
        if(sqlite3_step(statement) == SQLITE_DONE)
        {
            success = YES;
        }
        else
        {
            NSLog(@"%s: step not ok: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
        }
        sqlite3_finalize(statement);
    }
    else
    {
        NSLog(@"%s: prepare failure: %s", __FUNCTION__, sqlite3_errmsg(appDelegate->globalConnection));
    }

    return success;
}
Related Topic