Probleme beim Codieren während INSERT mit Sqlite3 C ++ und VisualStudio2010

8

Ich entwickle einen kleinen Wrapper für ein Projekt mit sqlite3 mit der C ++ API und VisualStudio 2010. So weit wie es geht und mit einem Werkzeug wie SQLiteDataBaseBrowser überprüfen, ist das Hauptproblem, dass die Informationen, die ich versuche, in die Tabelle einzufügen erscheint beschädigt / erscheint überhaupt nicht. Die Tabelle scheint korrekt mit UTF8-Codierung erstellt worden zu sein.

Ich habe versucht, die Zeichensatzkonfigurationswerte in VS als "Use Multy-Byte Character set" zu verwenden und habe es auch mit "Use Unicode Character set" versucht, habe aber keine Änderung im Ergebnis. Beide gaben mir das gleiche Problem mit den beschädigten Daten. Ich benutze die typischen std :: strings konvertiert in Legacy c char * und wie ich in mehreren Beispielen gesehen habe, sollte es richtig mit sqlite3_bind_text (...) funktionieren, die die API bereitstellt.

%Vor%

newShop ist eine Instanz einer Klasse, die die Informationen in std :: strings und int enthält. Ich muss sagen, dass die Bindungen mit Int-Typ perfekt und ohne Probleme funktionieren, aber die anderen sehen total durcheinander aus. Wenn die Strings fest codiert sind, sehen sie auch in Ordnung aus, bis ich versuche, Sonderzeichen wie "áàä" und so einzufügen.

Die Tabelle wird mit der folgenden Anweisung erstellt:

%Vor%

So sieht es aus, wenn ich die Daten mit dem obigen Code-Snippet einfüge:

sendet es aus einem WINUNIT-Test, der wie folgt aussieht:

%Vor%

Weder das Einfügen, das Commit, das Erstellen der SQL-Anweisung oder irgendein anderer Funktionsaufruf an die API von sqlite3 gibt einen Fehlercode zurück.

    
Ed. 26.04.2015, 11:12
quelle

2 Antworten

3

Ich habe die Lösung gefunden. Es hatte nichts mit der Kodierung zu tun, wie ich dachte, weil die Zeichen im DB-Browser seltsam dargestellt sind und auch nichts mit der Länge zu tun hat.

Das Problem lag im letzten Parameter der Bindung. Wo ich SQLITE_STATIC übergebe, hätte ich SQLITE_TRANSIENT übergeben sollen, da das Objekt, das von den Anrufen zurückgegeben wird, die ich binden möchte, möglicherweise zerstört werden, bevor die Abfrage ausgeführt wird. So wie es in dieser anderen Frage erklärt wird:

sqlite3_bind_text SQLITE_STATIC vs SQLITE_TRANSIENT für c ++ - Zeichenfolge

    
Ed. 30.04.2015, 11:33
quelle
2

Ich denke sqlite-Referenz ist ziemlich klar über die API-Nutzung.

  

In diesen Routinen, die ein viertes Argument haben, ist der Wert die Zahl   von Bytes im Parameter. Um es klar zu sagen: Der Wert ist die Anzahl von   Bytes im Wert, nicht die Anzahl der Zeichen.

Gemäß Ihrer Verwendung

sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC); das vierte Argument ist -1 . Es sollte jedoch entweder newShop.GetName().length oder strlen (newShop.GetName (). C_str ()) '

sein
  

Hinweis: Seien Sie vorsichtig, wenn Sie mit Zeichenfolgen mit mehreren Zeichen arbeiten.   Wo strlen(chinese string) ! = chinese string.len . Weitere Informationen finden Sie hier .

    
VISWA KSP 28.04.2015 12:03
quelle