2015-04-26 14 views
8

Sto sviluppando un piccolo wrapper per un progetto che utilizza sqlite3 con l'API C++ e VisualStudio 2010. Per quanto riguarda il controllo e con uno strumento come SQLiteDataBaseBrowser, il problema principale è che le informazioni che cerco di inserire nella tabella appaiono danneggiate/non appaiono affatto. La tabella sembra essere creata correttamente con la codifica UTF8.Problemi di codifica durante INSERT con Sqlite3 C++ e VisualStudio2010

Ho provato a utilizzare i valori di configurazione del set di caratteri in VS come "Usa set di caratteri Multy-Byte" e ho anche provato con "Usa set di caratteri Unicode" ma non ho ottenuto alcun cambiamento nel risultato. Entrambi mi hanno dato lo stesso problema con i dati corrotti. Io uso il tipico std :: strings convertito in legacy c char * e come ho visto in diversi esempi che dovrebbe funzionare correttamente con le funzioni sqlite3_bind_text (...) fornite dall'API.

newShop è un'istanza di una classe che contiene le informazioni in std :: stringhe e int. Devo dire che i collegamenti con tipo int, funzionano perfettamente e senza problemi, ma gli altri sembrano completamente incasinati. quando le stringhe sono hardcoded, sembrano ok anche se provo a inserire caratteri speciali come "áàä" e così via.

La tabella viene creata con l'affermazione:

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

Questo è come appare quando inserisco i dati utilizzando il frammento di codice di cui sopra:

DataBase encoding problems

inviarlo da un test WinUnit che assomiglia a:

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

Né il l'inserimento, il commit, la creazione dell'istruzione sql o qualsiasi altra chiamata di funzione all'API sqlite3 restituiscono un codice di errore.

+0

Qual è la codifica di questi 'std :: string's? –

+0

Come hai creato il tavolo? quale tipo hai usato per il testo? – SHR

+0

Le stringhe sono base std :: stringhe. La tabella è creata come: 'char * szSQL =" CREA TABELLA SE NON ESISTE NEGOZI (ID INTEGER PRIMARY KEY NOT NULL, NOME TESTO NON NULL, TESTO POSIZIONE, TESTO PICTUREPATH, REGISTRO TESTO, TESTO MIS., TESTO UTENTI, DISPONIBILE INTEGER NOT NULL); "; int rc = sqlite3_exec (db, szSQL, NULL, 0, NULL); ' –

risposta

3

Ho trovato la soluzione. Non era niente legato alla codifica, come pensavo a causa dei personaggi rappresentati in modo strano nel browser DB e anche nulla legato alla lunghezza.

Il problema era nell'ultimo parametro del collegamento. Dove passo SQLITE_STATIC, avrei dovuto passare SQLITE_TRANSIENT, in quanto l'oggetto restituito dalle chiamate che desidero eseguire il binding è possibilmente distrutto prima dell'esecuzione della query.Così come è spiegato in quest'altra domanda:

sqlite3_bind_text SQLITE_STATIC vs SQLITE_TRANSIENT for c++ string

2

Penso che sqlite reference sia piuttosto chiaro sull'utilizzo dell'API.

In quelle routine che hanno un quarto argomento, il suo valore è il numero di byte nel parametro. Per essere chiari: il valore è il numero di byte nel valore, non il numero di caratteri.

Come per l'uso,

sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC); 4 ° arguement è -1. Tuttavia dovrebbe essere o newShop.GetName().length o strlen (newShop.GetName() c_str().) `

Nota: fare attenzione quando si tratta con stringa con caratteri multi-larghezza. Dove strlen(chinese string) ! = chinese string.len. Per ulteriori dettagli, consultare here.

+0

Per quanto ne so e sono stato in grado di vedere in alcuni esempi sul Web, specificando la dimensione della stringa è una buona pratica per il miglioramento della velocità. Quando si mette semplicemente un -1 come parametro, sqlite indovina la dimensione da sola, quindi questo non dovrebbe essere il problema (e non lo è, secondo i miei test). –

+0

@Ed stai riscontrando lo stesso errore, anche dopo aver specificato esplicitamente la lunghezza? –

+0

Sì, ho anche provato un testo vincolante come questo 'sqlite3_bind_text (stmt, 2," hardcoded ", -1, SQLITE_STATIC);' e non ha avuto problemi con le dimensioni. Quindi direi che non è un problema con questo argomento. –

Problemi correlati