这是一个奇怪的问题。我找到了一个有效的解决方法,但我想了解原因,因为我怀疑它会在我的代码中稍后出现。这是解决问题的方法:
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?或者代码还有其他问题吗?
答案 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