FMDatabase查询适用于?但是文字失败了

时间:2012-12-07 15:30:40

标签: objective-c nsstring fmdb

这是一个奇怪的问题。我找到了一个有效的解决方法,但我想了解原因,因为我怀疑它会在我的代码中稍后出现。这是解决问题的方法:

FMDatabase *cardDatabase // initialized elsewhere
NSString *cleanChar; // this is the sanitized query string 
NSString *cardQueryString;
int cardID;

switch ([self studyLanguage])
{
    case CSStudyLanguageMandarinTraditional:
        cardQueryString = @"SELECT rowid, * FROM trad_char WHERE search = ";
        break;

// [...other cases...]

}

cardQueryString = [cardQueryString stringByAppendingString:cleanChar];

[cardDatabase open];
FMResultSet* cardSet = [cardDatabase executeQuery:cardQueryString];

BOOL foundCard = NO;

while ([cardSet next])
{ 
    foundCard = YES;
    cardID = [cardSet intForColumn:@"rowid"];
}

[cardDatabase close];

此代码提供数据库错误:

DB Error 1: no such column: 意

其中“意”是我在cleanChar中传递的字符序列,显然被视为列而不是某种方式的值。但是......如果我在查询步骤中添加搜索字符,如下所示:

cardQueryString = @"SELECT rowid, * FROM trad_char WHERE search = ?";
FMResultSet* cardSet = [cardDatabase executeQuery:cardQueryString, cleanChar];

一切正常。

所以我实际上已经解决了这个问题...但是我想知道为什么,因为它会影响我想要做一些更复杂的查询的方式,其中有多个连接在路上,在那里它会更难只需在最后插入变量。

所以:这是FMDatabase中的错误吗?我只是不明白如何使用FMDatabase?或者代码还有其他问题吗?

1 个答案:

答案 0 :(得分:0)

您的查询失败,因为您没有将搜索字符串包装在单引号中(用于指定文字)。所以你需要替换这一行

cardQueryString = [cardQueryString stringByAppendingString:cleanChar];

用这个:

cardQueryString = [NSString stringWithFormat:@"%@'%@'", cardQueryString cleanChar];

然而,通过使用NSString方法组合查询字符串和查询参数来组合查询是不好的做法。这有几个原因是有问题的,例如,如果参数包含保留字符或单词,或者转义序列可以打开SQL注入问题。

您应该通过SQLite的绑定机制提供参数,这些绑定机制很好地包含在FMDB方法中。所以,你的“解决方法”实际上是最好的方法:

cardQueryString = @"SELECT rowid, * FROM trad_char WHERE search = ?";
FMResultSet* cardSet = [cardDatabase executeQuery:cardQueryString, cleanChar];

或在数组中发送一个或多个参数:

cardQueryString = @"SELECT rowid, * FROM trad_char WHERE search = ?";
FMResultSet* cardSet = [cardDatabase executeQuery:cardQueryString arguments:@[cleanChar]];

汤姆
BareFeetWare