Вопрос

I am creating a temp table using the following SQL query. But its not showing any results (result set is empty) when I execute it programmatically, and shows records when I execute it manually on the database.

NSString *query=[NSString stringWithFormat:@"create temp table search2 as select  Observationsid from Observations where admin_id=%d AND teacher_id=%d AND observation_type=%d AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'",appDelegate.admin_id,appDelegate.teacher_id,appDelegate.observationType];
FMResultSet *results=[appDelegate.database executeQuery:query];

Nslogged query: Printing description of results->_query:

create temp table search2 as select Observationsid from Observations where admin_id=2 AND teacher_id=1 AND observation_type=2 AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'

and records are there in database.

Это было полезно?

Решение

This SQL statement shouldn't return results, so you should use executeUpdate method rather than a executeQuery method. You should not see any results from this. If you want to see the results, do a separate executeQuery statement returning the results from search2. (I assume you're building the search2 table for a reason.)

NSString *query=[NSString stringWithFormat:@"create temp table search2 as select  Observationsid from Observations where admin_id=%d AND teacher_id=%d AND observation_type=%d AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'",appDelegate.admin_id,appDelegate.teacher_id,appDelegate.observationType];
if (![appDelegate.database executeUpdate:query])
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]);

query = @"SELECT * FROM search2";
FMResultSet *results = [appDelegate.database executeQuery:query];
if (!results)
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]);

By the way, while you can get away with stringWithFormat for this particular SQL, that's not a good idea. You generally want to use the ? placeholders, e.g.

NSString *query = @"create temp table search2 as select  Observationsid from Observations where admin_id=? AND teacher_id=? AND observation_type=? AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'";
if (![appDelegate.database executeUpdate:query, @(appDelegate.admin_id), @(appDelegate.teacher_id), @(appDelegate.observationType)])
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]);

Unrelated, but I notice that you're using MM-DD-YYYY format text string for your dates. That's not going to work. SQLite doesn't natively "understand" dates. Notably, if you've stored your dates in MM-DD-YYYY format, a text string of 12-21-2052 is BETWEEN '12-20-2013' AND '12-23-2013' (because text strings are compared in alphabetically order), which is probably not what you intended. See Date And Time Functions.

But, fortunately, FMDB does the NSDate conversion for you, storing it as numeric value. So, for example, let's assume your table was defined as follows:

CREATE TABLE IF NOT EXISTS Observations
    (Observationsid   INTEGER PRIMARY KEY AUTOINCREMENT, 
     admin_id         INTEGER, 
     teacher_id       INTEGER,
     observation_type INTEGER,
     isvalid          TEXT,
     date             REAL);

You really want to use YYYY-MM-DD or, better, rely upon FMDatabase to convert your NSDate values for you. Remember, SQLite does not have proper date formats, so choose an appropriate format (e.g. YYYY-MM-DD format) or let FMDatabase handle this for you, using NSDate objects.

If you want to facilitate the conversion of date strings to dates, you can use a NSDateFormatter, e.g.:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"MM-dd-yyyy";

NSDate *someDate = [formatter dateFromString:@"12-22-2013"];
if (![appDelegate.database executeUpdate:@"INSERT INTO Observations (admin_id, teacher_id, observation_type, isvalid, date) VALUES (?, ?, ?, ?, ?)", @(appDelegate.admin_id), @(appDelegate.teacher_id), @(appDelegate.observationType), @"yes", someDate])
    NSLog(@"insert error: %@", [appDelegate.database lastErrorMessage]);

Or, if I wanted to select the dates between these two dates:

NSDate *startDate = [formatter dateFromString:@"12-20-2013"];
NSDate *endDate   = [formatter dateFromString:@"12-23-2013"];

NSString *query = @"create temp table search2 as select  Observationsid, date from Observations where admin_id=? AND teacher_id=? AND observation_type=? AND isvalid='yes' AND date BETWEEN ? AND ?";
if (![appDelegate.database executeUpdate:query, @(appDelegate.admin_id), @(appDelegate.teacher_id), @(appDelegate.observationType), startDate, endDate])
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]);

query = @"SELECT * FROM search2";
FMResultSet *results = [appDelegate.database executeQuery:query];
if (!results)
    NSLog(@"select error: %@", [appDelegate.database lastErrorMessage]);
while ([results next])
    NSLog(@"%d %@", [results intForColumnIndex:0], [results dateForColumnIndex:1]);

If you want to avoid this NSDate logic, you could alternatively consciously store dates in a text format in YYYY-MM-DD format. That works, too. Again, see that Date and Time Functions page for a list of valid text formats for dates.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top