2009-12-07 46 views
0

首先請讓我說我對客觀的C開發很陌生。我寫自用的iPhone一個小應用程序,但我必須執行以下代碼一些問題:如何將Cocoa的值傳遞給SQLite查詢

NSString *sql = [[NSString alloc] initWithFormat:@"select color_r, color_g, color_b from Calendar where ROWID = %@", [calendarsID objectForKey:[arrayColors objectAtIndex:row]]]; 

sqlite3_stmt *selectstmt; 

if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) 

編譯器告訴我,我傳遞sqlite3_prepare_v2的參數2不兼容的指針類型。無論如何,程序都會被編譯並運行,但是,當它必須執行我剛剛向您顯示的代碼時,它會產生錯誤。它表示查詢中存在語法錯誤,語法錯誤僅在查詢的最後部分。相反,具有:

選擇color_,color_g,color_b從日曆,其中ROWID = 63(例如)

我在過去數(63)的地方得到奇怪的字符。我想這是一個與字符串轉換有關的問題。可以請anyhone幫我嗎?

非常感謝您的關注。 阿萊西奧

+1

Ewww ...爲什麼*你會直接違反SQLite API?首先,CoreData比API更容易使用,並且在設備上本地支持。其次,正如戴夫所說,有一堆包裝紙。 – bbum 2009-12-07 02:19:02

+0

我告訴過你我並不那麼有經驗。你知道有什麼好的網站可以在SQLite包裝器和/或CoreData上獲得文檔(和例子)嗎? 謝謝。 – Alessio 2009-12-07 10:29:42

回答

6

的問題是,一個NSString是不是sqlite3_prepare_v2()期待它的第二個參數。它想要一個const char*。 C在這裏有點鬆懈,它可以讓你隱式地將NSString*轉換爲const char*,這是錯誤的 - 編譯器給你一個警告,你不應該忽略。您需要將NSString轉換爲const char*。要做到這一點最簡單的方法是使用-UTF8String消息將其轉換爲UTF-8:

//        V---- HERE ----V 
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) 

或者,在您要使用不同的編碼較少的情況下,你可以使用-cStringUsingEncoding:消息轉換將字符串轉換爲使用特定字符編碼的C字符串。

+0

完美的謝謝,這正是我正在尋找,現在它工作正常。 Tnx ;-) – Alessio 2009-12-07 10:38:12

0

阿萊西奧,

這將是更容易被更多的細節來回答這個問題。例如,arrayColors中有哪些類型的對象?

如果arrayColors中的對象不是NSString,那麼您需要調用一個方法(例如description)來創建一個NSString表示。

亞倫

1

爲什麼你不使用SQLite的value binding API之一?聲明看起來像

SELECT color_r, color_g, color_b FROM Calendar WHERE ROWID = ?; 

而且你會直接將參數傳遞給SQLite,因爲它可以安全地插入到查詢中。這將保護您免受SQL注入攻擊。 (您顯示的示例可能是是安全的,這取決於這些值最終來自哪裏,但使用sprintfstringWithFormat:來構建SQL查詢是一個非常非常不好的習慣,請勿搞砸Little Bobby Tables

至於你爲什麼遇到這個問題,SQLite不接受類似NSString *的可可類型。當您切換到使用SQLite格式化查詢時,您將能夠從文檔中學習您應該使用哪種類型。然後,您可以提出有關如何執行轉換的另一個問題。

+0

我同意你的看法,但正如我已經說過的,我並不擅長這些API,也沒有使用編程語言。無論如何,在我的情況下,輸入是安全的,因爲它不是來自用戶,但爲了更安全,我將按照您的建議實施值綁定。 Tnx ;-) – Alessio 2009-12-07 10:39:28

+0

值綁定也快得多。通常快三倍。 – tuinstoel 2009-12-10 19:42:47