簡體   English   中英

使用Sqlite3 C ++和VisualStudio2010在INSERT期間編碼問題

[英]Encoding problems during INSERT with Sqlite3 C++ and VisualStudio2010

我正在使用sqlite3和C ++ API以及VisualStudio 2010為一個項目開發一個小包裝器。就像使用SQLiteDataBaseBrowser這樣的工具進行檢查一樣,主要問題是我嘗試在表中插入的信息顯示為損壞/根本沒有出現。 該表似乎是使用UTF8編碼正確創建的。

我嘗試將VS中的字符集配置值用作“使用多字節字符集”,並嘗試使用“使用Unicode字符集”,但結果沒有變化。 兩者都給我帶來了與損壞數據相同的問題。 我使用典型的std :: strings轉換為legacy c char *,正如我在幾個例子中看到的,它應該與API提供的sqlite3_bind_text(...)函數一起正常工作。

    sqlite3_bind_int(stmt, 1, newShop.GetId());
    sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 3, newShop.GetLocation().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 4, newShop.GetPicturePath().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 5, newShop.GetRegisters().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 6, newShop.GetMixes().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 7, newShop.GetAllowedUsers().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 8, newShop.IsAvailable() == true?1:0);

newShop是一個類的實例,它包含std :: strings和int中的信息。 我不得不說使用int類型的綁定,工作完美且沒有問題,但其他人看起來完全搞砸了。 當字符串被硬編碼時,它們看起來還不錯,直到我嘗試插入特殊字符,如“áàä”等。

該表是使用以下語句創建的:

char *szSQL = "CREATE TABLE IF NOT EXISTS SHOPS (ID INTEGER PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, LOCATION TEXT, PICTUREPATH TEXT, REGISTERS TEXT, MIXES TEXT, USERS TEXT, AVAILABLE INTEGER NOT NULL);";
int rc = sqlite3_exec(db, szSQL, NULL, 0, NULL);

這是我使用上面的代碼片段插入數據時的外觀:

DataBase編碼問題

從WINUNIT測試發送它看起來像:

Shop shOne = Shop(1234, "Its about nothing", "Manhattan", "seinfeld.jpg", "1111,2222,3333", "1000x1,2000x7", "10,11,12", true); 
Shop shTwo = Shop(4321, "Louie", "Manhattan", "", "1111,5555", "50000x1,10000x5", "60,70", true);

WIN_ASSERT_EQUAL(0, auxsql.InsertShop(shOne));
WIN_ASSERT_EQUAL(0, auxsql.InsertShop(shTwo));

插入,提交,創建sql語句或對sqlite3 API的任何其他函數調用都不會返回錯誤代碼。

我找到了解決方案。 它與編碼無關,正如我想的那樣,因為在DB瀏覽器中奇怪地表示了字符,而且與長度無關。

問題出在綁定的最后一個參數中。 在我傳遞SQLITE_STATIC的地方,我應該傳遞SQLITE_TRANSIENT,因為我想要綁定的調用返回的對象可能在執行查詢之前被破壞。 正如在另一個問題中解釋的那樣:

sqlite3_bind_text用於c ++字符串的SQLITE_STATIC與SQLITE_TRANSIENT

我認為sqlite引用非常清楚API的用法。

在具有第四個參數的那些例程中,其值是參數中的字節數。 要清楚:值是值中的字節數,而不是字符數。

根據您的使用情況,

sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC); 第四個論點是-1 但它應該是newShop.GetName().length或strlen(newShop.GetName()。c_str())`

注意:處理具有多寬字符的字符串時要小心。 strlen(chinese string) ! = chinese string.len strlen(chinese string) ! = chinese string.len 請參閱此處了解更多詳情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM