I am creating an iOS app that reads data from a single SQLITE table using variables. I don't have a problem running my select statement when all variables are populated, but I want to eventually have a large am开发者_Python百科ount of variables and allow the users to skip ones that they don't see as meaningful to them. In other words, how can I make this work even when variables are null or 0 such as ignoring that part of the select statement, but continuing on? I have tried to use IF statements or CASE statements, but then I get the undeclared error. I could repeat the entire getInitialDataToDisplay with IFs, but there has to be an easier way.
+ (void) getInitialDataToDisplay:(NSString *)dbPath{
int addOne = [[NSUserDefaults standardUserDefaults] integerForKey: @"criterion1key"];
int addTwo = [[NSUserDefaults standardUserDefaults] integerForKey: @"criterion2key"];
int addThree = [[NSUserDefaults standardUserDefaults] integerForKey: @"criterion3key"];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
NSString *querystring= [NSString stringWithFormat:@"select * from animalswhere description > %i and description < %i and cash >= %i",addOne, addTwo, addThree]; //WORKS FINE IF ALL VARIABLES HAVE VALUES, BUT DOES NOTHING IF VARIABLES ARE EMPTY
const char *sql = [querystring UTF8String];
sqlite3_stmt *selectstmt; if(sqlite3_prepare_v2(database, sql, -1,&selectstmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(selectstmt) ==
SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Animal *animal = [[Animal alloc] initWithPrimaryKey:primaryKey];
animal.name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)];
animal.description = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)];
animal.imageURL = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 5)];
animal.cash = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 32)];
[appDelegate.animals addObject:animal];
[animal release];
}
}
} else sqlite3_close(database);
}
Sounds like what you need is to use marker variables/values, and a little boolean logic:
SELECT valuea, valueb, valuec
FROM table
WHERE valuea = %inputParmA
AND (%inputParmB = 0 OR valueb = %inputParmB)
This will have the effect of selecting all rows where valuea
matches the passed-in value (of inputParmA
), and, if inputParmB
is non-zero, valueb
matches inputParmB
.
You'll have to adapt this for your needs, but it's a quick-and-dirty alternative to using dynamic sql, if this isn't available (or difficult to generate).
Not completely sure about performance, but I have a query that has around a dozen of these, operating over a multi-million row database, and returns within a minute (hundreds of results).
精彩评论