views:

30

answers:

1

Trying to return whether a record exists in SQLite on the iPhone except I keep getting an 'unknown error'.

selectStmt is static sqlite3_stmt *selectStmt = nil; used here if(selectStmt) sqlite3_finalize(selectStmt); which only gets executed if the application terminates. This functionality works fine with delete statements and insert statements so I'm guessing it's something wrong with the below logic?

- (BOOL) doesBookExist {

    if(selectStmt == nil) {
        const char *sql = "select count(*) from books where isbn = ?";

        if(sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) != SQLITE_OK)
            NSAssert1(0, @"Error while creating select statement. '%s'", sqlite3_errmsg(database));
    }

    //When binding parameters, index starts from 1 and not zero.
    int count = sqlite3_bind_text(selectStmt, 1, [isbn UTF8String], -1, SQLITE_TRANSIENT);

    if (SQLITE_DONE != sqlite3_step(selectStmt)) 
        NSAssert1(0, @"Error while selecting. '%s'", sqlite3_errmsg(database));

    sqlite3_reset(selectStmt);

    return (count > 0);
}
+1  A: 

sqlite3_bind_text returns a success/error code, not the result of any query. And step should return SQLITE_ROW, since you have one row of result data (regardless of whether the count is 0 or more). There seemed to be an error, because you were expecting SQLITE_DONE when the correct value was SQLITE_ROW. Then, to get the count, you need to use sqlite3_column_int after executing step. So something like:

int bind_res = sqlite3_bind_text(selectStmt, 1, [isbn UTF8String], -1, SQLITE_TRANSIENT);

if (SQLITE_OK != bind_res)
{
  // log error, return...
}

// One row of result data, so step should return SQLITE_ROW
if (SQLITE_ROW != sqlite3_step(selectStmt)) 
{
  NSAssert1(0, @"Error while selecting. '%s'", sqlite3_errmsg(database));
  // log error, return
}

int count = sqlite3_column_int(selectStmt, 0); 
Matthew Flaschen
This makes perfect sense and it works exactly how I wanted it to work. Thank, you.
Fulvio