FMDB sqlite 的 sql 查询不起作用



我正在使用以下SQL查询创建一个临时表。但当我以编程方式执行它时,它不会显示任何结果(结果集为空),当我在数据库上手动执行它时会显示记录。

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:

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'

并且记录在数据库中。

这个SQL语句不应该返回结果,所以应该使用executeUpdate方法,而不是executeQuery方法。你不应该从中看到任何结果。如果要查看结果,请执行一个单独的executeQuery语句,从search2返回结果。(我认为您构建search2表是有原因的。)

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]);

顺便说一句,虽然您可以为这个特定的SQL使用stringWithFormat,但这不是一个好主意。您通常希望使用?占位符,例如

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]);

不相关,但我注意到您的日期使用的是MM-DD-YYYY格式的文本字符串。这行不通。SQLite本身并不"理解"日期。值得注意的是,如果您将日期存储为MM-DD-YYYY格式,那么12-21-2052的文本字符串就是BETWEEN '12-20-2013' AND '12-23-2013'(因为文本字符串是按字母顺序进行比较的),这可能不是您想要的。请参阅日期和时间函数。

但是,幸运的是,FMDB为您进行NSDate转换,并将其存储为数值。因此,例如,让我们假设您的表定义如下:

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

您确实希望使用YYYY-MM-DD,或者更好地,依靠FMDatabase来为您转换NSDate值。请记住,SQLite没有合适的日期格式,所以请选择合适的格式(例如YYYY-MM-DD格式),或者让FMDatabase使用NSDate对象为您处理此问题。

如果您想方便将日期字符串转换为日期,可以使用NSDateFormatter,例如:

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]);

或者,如果我想在这两个日期之间选择日期:

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]);

如果您想避免这种NSDate逻辑,您可以有意识地将日期存储为YYYY-MM-DD格式的文本格式。这也行得通。同样,请参阅"日期和时间函数"页面,以获取日期的有效文本格式列表。

最新更新