我很好奇我在使用iOS模拟器/设备和Mac OSX附带的sqlite3命令行应用程序时遇到的差异。
在另一台机器(我的Windows机器)上,我用文本文件创建了一个sqlite数据库。这是SQLite文件的create语句。
CREATE TABLE IF NOT EXISTS GeocodeData (ZipCode TEXT, City TEXT COLLATE NOCASE, State TEXT COLLATE NOCASE, Latitude REAL, Longitude REAL, PRIMARY KEY(ZipCode, City, State) ON CONFLICT INGORE);
我正在使用COLLATE NOCASE
,因为我发现on this SO question有不区分大小写的搜索。
当我将数据库移动到我的Mac,在终端中运行sqlite3
应用程序时,我可以运行以下查询:
SELECT * FROM GeocodeData WHERE City = 'elyria' AND State = 'oh'
。
44035|Elyria|OH|41.3724|-82.1051
44036|Elyria|OH|41.4015|-82.0771
运行此语句将从我的数据库返回2个结果。真棒。
转到我正在创建的iPad应用程序,我正在使用FMDatabase来包装对Sqlite数据库的访问。
这是访问它的代码。
+(CLLocationCoordinate2D)getCoordinateForFilter:(GeocodingFilter *)filter
{
__block CLLocationCoordinate2D coordinate;
FMDatabaseQueue *queue = [self databaseQueue];
[queue inDatabase:^(FMDatabase *db)
{
//Determine if we're using zipcode or city/state.
NSMutableString *query = [[NSMutableString alloc] initWithString:SELECT_STATEMENT];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
if(![NSString isNilOrWhitespace:filter.zipCode])//Zipcode logic
{
[query appendFormat:WHERE_CLAUSE, @"ZipCode = :zipCode "];
params[@"zipCode"] = filter.zipCode;
}
else
{
NSString *clause = nil;
if(![NSString isNilOrWhitespace:filter.city])
{
clause = [NSString stringWithFormat:WHERE_CLAUSE, @"City = :city"];
params[@"city"] = filter.city;
}
if (![NSString isNilOrWhitespace:filter.state])
{
if(clause)
clause = [NSString stringWithFormat:@"%@ AND", clause];
clause = [NSString stringWithFormat:@"%@ State = :state", clause];
params[@"state"] = filter.state;
}
[query appendString:clause];
}
FMResultSet *set = [db executeQuery:query withParameterDictionary:params];
NSMutableArray *results = [NSMutableArray array];
while ([set next])
{
double latitude = [set doubleForColumn:@"Latitude"];
double longitude = [set doubleForColumn:@"Longitude"];
[results addObject:[[CLLocation alloc] initWithLatitude:latitude longitude:longitude]];
}
[set close];
[db close];
__block double avgLat = 0.;
__block double avgLong = 0.;
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CLLocation *loc = obj;
avgLat += loc.coordinate.latitude;
avgLong += loc.coordinate.longitude;
}];
coordinate = CLLocationCoordinate2DMake(avgLat/(double)results.count, avgLong/(double)results.count);
}];
return coordinate;
}
这运行与我在sqlite3命令行中使用的完全相同的查询,但每次都返回0结果。
现在,我可以通过更改这4行代码来解决问题。
clause = [NSString stringWithFormat:WHERE_CLAUSE, @"City LIKE :city"];
params[@"city"] = [NSString stringWithFormat:@"%%%@%%", filter.city];
和
clause = [NSString stringWithFormat:@"%@ State LIKE :state", clause];
params[@"state"] = [NSString stringWithFormat:@"%%%@%%", filter.state];
但是我明确地创建了表以在create语句中使用COLLATE NOCASE
。为什么这不起作用?
编辑:显然我需要重新解决问题。问题是不 LIKE
查询!
我想知道为什么这个查询:SELECT * FROM GeocodeData WHERE City = 'elyria' AND State = 'oh'
在命令行上返回2个结果,而在iOS环境中运行 THIS EXACT SAME QUERY ,FMDatabase返回0结果。
答案 0 :(得分:1)
我承认SQLite文档在某些地方组织得很差,但对于一个开源项目来说,它的准确性和精确度都是如此。
咨询文档表明你不应该遇到你所描述的问题,最终会得出一些与你所描述的不同的结论。