ejemplo c++ visual-studio-2010 encoding utf-8 sqlite3

ejemplo - Problemas de codificación durante INSERT con Sqlite3 C++ y VisualStudio2010



sqlite c++ ejemplo (2)

Estoy desarrollando un envoltorio pequeño para un proyecto que usa sqlite3 con C ++ API y VisualStudio 2010. Por lo que se refiere y comprobando con una herramienta como SQLiteDataBaseBrowser, el problema principal es que la información que intento insertar en la tabla aparece dañada / no aparece en absoluto. La tabla parece haberse creado correctamente con la codificación UTF8.

Intenté usar los valores de configuración del conjunto de caracteres en VS como "Usar conjunto de caracteres de varios bytes" y también intenté con "Usar conjunto de caracteres Unicode" pero no obtuve ningún cambio en el resultado. Ambos me dieron el mismo problema con los datos corruptos. Utilizo las típicas std :: cadenas convertidas en legacy c char * y como he visto en varios ejemplos, debería funcionar correctamente con las funciones sqlite3_bind_text (...) que proporciona la API.

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 es una instancia de una clase que contiene la información en std :: strings e int. Debo decir que las vinculaciones con tipo int funcionan a la perfección y sin problemas, pero las otras parecen totalmente desordenadas. cuando las cadenas están codificadas, también se ven bien hasta que intento insertar caracteres especiales como "áàä" y tal.

La tabla se crea con la instrucción:

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

Así es como se ve cuando inserto los datos usando el fragmento de código anterior:

enviándolo desde una prueba WINUNIT que se ve así:

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

Ni la inserción, la confirmación, la creación de la instrucción sql o cualquier otra llamada de función a la API sqlite3 devuelve un código de error.


Creo que la referencia de sqlite es bastante clara sobre el uso de API.

En esas rutinas que tienen un cuarto argumento, su valor es la cantidad de bytes en el parámetro. Para ser claros: el valor es el número de bytes en el valor, no el número de caracteres.

Según su uso,

sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC); el cuarto argumento es -1 . Sin embargo, debe ser newShop.GetName().length Length o strlen (newShop.GetName (). C_str ()) `

Nota: tenga cuidado cuando trabaje con cuerdas con caracteres múltiples. ¡Donde strlen(chinese string) ! = chinese string.len strlen(chinese string) ! = chinese string.len Consulte aquí para más detalles.


Encontré la solución. No se trataba de nada relacionado con la codificación, ya que pensé que los personajes estaban extrañamente representados en el navegador DB y tampoco nada relacionado con la longitud.

El problema estaba en el último parámetro de la vinculación. Donde paso SQLITE_STATIC, debería haber pasado SQLITE_TRANSIENT, ya que el objeto devuelto por las llamadas que quiero enlazar posiblemente se destruya antes de que se ejecute la consulta. Tal como se explica en esta otra pregunta:

sqlite3_bind_text SQLITE_STATIC vs SQLITE_TRANSIENT para cadena de c ++