I have this sqlite3 table used in an iOS 6 app for iPad:
CREATE TABLE notes(id INTEGER PRIMARY KEY, note TEXT, noteDate TEXT, wasUploaded INTEGER);
from the sqlite3 command line this query works:
sqlite> Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `wasUploaded`=0;
1|Well|2012-10-04 22:46:23|0
On iOS iPad 6.0 Simulator each of these queries returns the exact same data as above:
const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `id`=1";
const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `note`='Well'";
const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `noteDate`='2012-10-04 22:46:23'";
But this query which worked fine on the command line now returns no data:
const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `wasUploaded`=0";
Has me baffled. Why is that last query not working? Do I need to make that column an index or something? The other two non-indexed columns work but not this.
No errors. The last query that returns no data gives a normal return code of 101 (sqlite3_step() has finished executing) and a query without the where clause returns the same data as for the other three queries.
Edit: here is the complete code
- (NSString *)getNotesToBeUploaded {
sqlite3 *stuDb;
NSString *thisNote;
NSMutableString *notes = [[NSMutableString alloc]init];
if (self.filePath == @"empty") {
[self setDatabaseFilePath];
}
if (sqlite3_open([self.filePath UTF8String], &stuDb) == SQLITE_OK)
{
// this is the query line that get changed to show stackoverflow the different results:
const char *sqlStatement = "Select `id`,`note`,`noteDate` FROM notes WHERE `wasUploaded`=0";
sqlite3_stmt *compiledStatement;
int nResult = sqlite3_prepare_v2(stuDb, sqlStatement, -1, &compiledStatement, NULL);
if ( nResult == SQLITE_OK)
{
int nret; // diagnostic used to watch return vaues when single stepping
while ((nret = sqlite3_step(compiledStatement)) == SQLITE_ROW)
{
int id = sqlite3_column_int(compiledStatement, 0);
const unsigned char *note = sqlite3_column_text(compiledStatement, 1);
const unsigned char *noteDate = sqlite3_column_text(compiledStatement, 2);
int wu = sqlite3_column_int(compiledStatement, 4);
if (strlen((const char *)note) > 0 && strlen((const char *)noteDate) > 0)
{
thisNote = [NSString stringWithFormat:@"%d,%s,%s,%d\n",id, noteDate, note, wu];
[notes appendString:thisNote];
}
}
} else {
sqlite3_finalize(compiledStatement);// prevent small memory leaks
sqlite3_close(stuDb);
thisNote =
[NSString stringWithFormat:@"prepare failed with status:%d in %s at line %d path was %@,0,0\n",nResult,__FILE__,__LINE__,self.filePath];
[notes appendString:thisNote];
[notes appendString:@"\n"];
return (NSString *)notes;
}
sqlite3_finalize(compiledStatement);
sqlite3_close(stuDb);
}
Are you checking the return codes from your
sqlite3calls? And, if you’re not gettingSQLITE_OKorSQLITE_ROW, as appropriate, you should check thesqlite3_errmsgresults to diagnose what’s going on. You really should share your code if you want us to help you.But the most common problems in the first-time iOS SQLite apps are
Failing to include the database in your app’s bundle. Check your Target settings and make sure you’ve included the database in the
Build Phases. You can also confirm this by looking at your app’s bundle in the simulator in the~/Library/Application Support/iPhone Simulatorfolder. If you want to do that, you may want to unhide your~/Libraryfolder if you haven’t by typing inchflags no hidden ~/Libraryin the Terminal command line interface.If you’re planning on updating your database from the app, failing to first copy the database from the bundle to the
Documentsfolder before you try to start using it.Using
sqlite3_openand interpreting a successful return code as evidence that the database was opened successfully … but if it didn’t find the database, thesqlite3_openfunction annoyingly will create a new blank database … I always suggest that people usesqlite3_open_v2instead, in which you can omit the parameter to create a blank database if it’s not found if that’s not what you want.Certainly, there can be a ton of code-related issues (order that the functions are called, failing to check return codes, etc.), too. It’s impossible to comment further without seeing the code.
And I feel obliged to share my final SQLite programming advice that it’s worth checking out FMDB Objective-C SQLite wrapper library, which greatly simplifies SQLite programming in iOS.
Update:
Having looked at your code, it looks fine. I just ran it (only tweaked to just
NSLograther than appending notes):And I got results:
So the problem must be in the database itself. Judging from your last comment, it sounds like rebuilding the database did it for you. That’s great.