2013-12-23 169 views
2

我正在使用以下SQL查询创建临时表。但是,当我以编程方式执行它时没有显示任何结果(结果集为空),并且在数据库上手动执行它时显示记录。FMDB sqlite的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查询:结果 印刷说明 - > _查询:

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' 

和记录有在数据库中。

+0

不相关,但我注意到你的日期使用了“MM-DD-YYYY”格式。你真的想使用'YYYY-MM-DD',或者更好地依靠'FMDatabase'来为你转换你的'NSDate'值。但是如果你使用你所拥有的,'12-21-2052'的文本字符串是'BETWEEN '12 -20-2013'和'12 -23-2013',这可能不是你想要的。请记住,SQLite没有适当的日期格式,所以选择适当的格式(例如'YYYY-MM-DD'格式)或让'FMDatabase'使用'NSDate'对象为你处理。 – Rob

+0

@Rob非常感谢你。我对sqlite和nsdate的数据库日期格式的日期格式有困惑,但我没有努力提出问题。你会吹捧给我适当的例子或教程的链接,这将解释更多关于这一点。提前致谢。 – ViruMax

+0

我已经添加了一些示例日期逻辑到我的答案结束。 – Rob

回答

0

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

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

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'(因为文本字符串按字母顺序进行比较),这可能不是您想要的。见Date And Time Functions

但幸运的是,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,或者更好,依靠FMDatabaseNSDate值转换为您服务。请记住,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格式存储文本格式的日期。这也适用。同样,请参阅Date and Time Functions页面以获取日期的有效文本格式列表。

+0

非常感谢。 :)。我也在尝试FMResultSet * results = [appDelegate.database executeUpdate:query];但我使用FMResultSet,因此它给错误。 – ViruMax

+0

是的,一个问题是我不知道,sqlite存储日期数字格式,它由FMDatabase自动处理。 – ViruMax