iphone sqlite query crashes if no rows returned
iphone, sqlite
Solution
A. if sqlite3_step does not return any rows, you crash because you have declared that you are returning a NSString, but when there are no rows you return nothing. The caller will try to read a NSString from the stack and thus end up dereferencing garbage.
To quickly fix the problem, write:
sqlite3_close(database);
return nil;
}
and make sure the caller handles nil results.
B/ If you do have data, your code never gets to call sqlite3_finalize and sqlite3_close because you return early:
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
[..]
return returnString;
Problem
I have the following function in my iPhone project which works great...unless the query returns nothing and then the app crashes. It is being a pain to debug with none of the breakpoints being activated at all! I know this works as I pass in static stuff that is in the DB and it returns a value. ``` -(NSString *)getSomeText:(NSString *)toPass { sqlite3 *database; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"sf.sqlite"]; int strLength = 0; strLength = [toPass length]; if (strLength <3) return @"Unknown"; NSString *MIDstr; NSMutableString * toPass Copy = [NSMutableString stringWithString:toPass]; MIDstr = [toPassCopy substringWithRange:NSMakeRange(0, 3)]; // Open the database from the users filessytem if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { // Setup the SQL Statement and compile it for faster access NSString *BaseSQL = [NSString stringWithFormat:@"select * from MIDS where MID = '%@'",MIDstr]; NSLog(BaseSQL); const char *sqlStatement = [BaseSQL UTF8String]; //NSLog(BaseSQL); sqlite3_stmt *compiledStatement; if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { // Loop through the results and add them to the feeds array while(sqlite3_step(compiledStatement) == SQLITE_ROW) { NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]; NSString *returnString = [NSString stringWithFormat:@"%@",aName]; return returnString; } } // Release the compiled statement from memory sqlite3_finalize(compiledStatement); } sqlite3_close(database); } ```