views:

26

answers:

1

Hi, I am displaying the contacts on the table. Section I pass in the method is name of section i.e. A-Z.. and the index is the index of the row in that particular section. So to get the id based on the row I tapped in particular section,I wrote the following method. I am trying to get the id from the database whose values match with the query I pass. So if I check for the firstnames starting with letter 'A' there are around 4 values under section A. So I took a variable i and trying to increment until it finds the correct index such that it returns the id for that particular index. The condition validates but when I am trying to get the sid it throws objc_exception_throw. When I tried to add the debug point, I found that the exception is in this line and on debugger it says NSInvalidArgumentException: NULLcString..

Please help me..Its very urgent and I am clueless on what to do..Thanks for the help!!!

The error is on line where I get sid

Here is the method:

-(NSString *)getSugarIdNSString *)tableName bySectionNSString *)section andIndexint)inde
{
int i=0;
NSString *sid;
NSString *qsql = [[NSString stringWithFormat: @"SELECT sugar_id FROM CONTACTS WHERE first_name LIKE '%@",section] stringByAppendingString:@"%'"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2( db, [qsql UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
char * utf8string = (char *)sqlite3_column_text(statement, 1);
        if(i==index){
            sid = utf8string ? [[NSString stringWithUTF8String:utf8string] : nil;
        //  sid = [[NSString alloc]initWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
            break;
        }

i++;
}
}
return sid; 
}
+1  A: 

It means exactly what it says: you're passing in a NULL C-string, which often ins't valid.

char * utf8string = sqlite3_column_text(statement, 1);
sid = utf8string ? [NSString stringWithUTF8String:utf8string] : nil;

Other problems:

  • [[NSString stringWithFormat:@"... '%@",section] stringByAppendingString:@"%'"]; is better written as [NSString stringWithFormat:@"... '%@', section].
  • Instead of gluing strings together, consider using prepared statements:
    sqlite3_prepare_v2(db, "SELECT ... WHERE first_name LIKE ?1", -1, &statement, nil);
    sqlite_bind_text(statement, 1, [section UTF8String], -1, SQLITE_TRANSIENT);
  • I don't think Sqlite3 guarantees the order returned unless you haven an ORDER BY clause. Try "ORDER BY ROWID".
  • Stepping through all the rows is tedious. Consider "LIMIT 1 OFFSET ?2" (or the equivalent "LIMIT ?2, 1") and do sqlite3_bind_int(statement, 2, index).
  • Preparing a statement is expensive (often more expensive than actually executing it); it's worth caching them. You can use sqlite3_reset() to reset the statement and then bind new values to it.
  • Executing a statement for every query is also expensive. Why don't you just save all the rows returned into an array?
  • Your code leaks sid (just use +[NSString stringWithUTF8String:]).
  • Your code leaks statement (it should be freed with sqlite3_finalize()).
tc.
Thanks for the reply..that was very useful but the string always returns nil..can you please help me regarding this
racharambola
I got it..can you please explain how to use sqlite_bind_int and sqlite_reset..if possible with an example as I am a newbie..please help me..
racharambola
http://www.sqlite.org/c3ref/bind_blob.html
tc.
Thanksa lot tc..your advices are very helpful.. :)
racharambola