2012-12-07 77 views
0

失敗這是一個奇怪的問題。我發現了一個可行的解決方法,但我想明白爲什麼,因爲我懷疑它稍後會在我的代碼中再次出現。這裏是一個的給我這個問題的方法:FMDatabase查詢適用於?但與文字

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

由於您沒有用單引號(用於指定文字)包裝搜索字符串,因此您的查詢失敗。所以,你需要替換該行

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 arguments:@[cleanChar]]; 

湯姆
BareFeetWare

:在陣列

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

或發送一個或多個參數

相關問題