ios设备和sqlite3命令行之间的Sqlite差异

时间:2014-01-13 18:13:46

标签: ios sqlite

我很好奇我在使用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结果。

1 个答案:

答案 0 :(得分:1)

我承认SQLite文档在某些地方组织得很差,但对于一个开源项目来说,它的准确性和精确度都是如此。

咨询文档表明你不应该遇到你所描述的问题,最终会得出一些与你所描述的不同的结论。