0

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

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 吗?还是代码有其他问题?

4

1 回答 1

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

Tom
BareFeetWare

于 2012-12-19T02:42:24.507 回答