Frage

Ich arbeite an der Entwicklung einer C ++ API, die anwendungsspezifische Plugins verwendet Schnittstelle mit verschiedenen Datenbank-Engines ihre APIs und spezifische SQL verwenden Syntax.

Derzeit bin ich versucht, eine Art und Weise des Einsetzens BLOBs zu finden, aber da NULL ist das Endzeichen in C / C ++, wird das BLOB abgeschnitten, wenn die Konstruktion der INSERT INTO Abfrage-String. Bisher habe ich gearbeitet habe

//...
char* sql;
void* blob;
int len;
//...
blob = some_blob_already_in_memory;
len = length_of_blob_already_known;
sql = sqlite3_malloc(2*len+1);
sql = sqlite3_mprintf("INSERT INTO table VALUES (%Q)", (char*)blob);
//...

Ich gehe davon aus, dass, wenn es überhaupt möglich ist, es in der SQLite3 interaktiven Konsole zu tun, soll es möglich sein, das Query-String zu konstruieren, mit richtig NULL Zeichen entkommen. Vielleicht gibt es eine Möglichkeit, dies mit Standard-SQL zu tun, die auch von SQLite SQL-Syntax unterstützt wird?

Sicherlich muss jemand vor der gleichen Situation konfrontiert. Ich habe gegoogelt und einige Antworten gefunden, war aber in anderen Programmiersprachen (Python).

Vielen Dank im Voraus für Ihr Feedback.

War es hilfreich?

Lösung

Sie finden diese Funktion mit einer vorbereiteten Anweisung verwendet werden sollen.

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));

In C / C ++, die Standardmethode mit NULL-Werten in Strings zu tun ist, um entweder zu speichern den Anfang des Strings und eine Länge oder speichert einen Zeiger auf den Anfang eines Strings und einem bis zum Ende des Strings.

Andere Tipps

Vielen Dank nochmals für Ihr Feedback. Diesmal Ich berichte, wie ich das Problem mit Hilfe der Angaben hier zur Verfügung gestellten gelöst. Hoffentlich wird dies andere in der Zukunft helfen.

Wie die ersten drei Plakate vorgeschlagen, habe ich vorbereitete Anweisungen verwenden -. Zusätzlich, weil ich die Spalte Daten in immer Typen auch interessiert war, und ein einfache sqlite3_get_table() würde das nicht tun

Nachdem die SQL-Anweisung in der Form des folgenden konstanten Zeichenfolge vorbereiten:

INSERT INTO table VALUES(?,?,?,?);

es bleibt die Bindung des entsprechenden Wertes. Dies wird durch die Ausgabe so viele sqlite3_bind_blob() Anrufe wie die Spalten erfolgt. (I griff auch für andere „einfache“ Datentypen sqlite3_bind_text(), weil die API ich arbeite können ganze Zahlen übersetzen / Doppel / etc in einen String). Also:

void* blobvalue[4];
int blobsize[4];
char *tail, *sql="INSERT INTO table VALUES(?,?,?,?)";
sqlite3_stmt *stmt=0;
sqlite3 *db;
/* ... */
db=sqlite3_open("sqlite.db");
sqlite3_prepare_v2(db, 
                   sql, strlen(sql)+1, 
                   &stmt, &tail);
for(int i=0; i<4; i++)
    sqlite3_ bind_ blob(stmt, 
                        i+1, blobvalue[i], blobsize[i], 
                        SQLITE_TRANSIENT);
if(sqlite3_step(stmt)!=SQLITE_DONE) 
    printf("Error message: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt);
sqlite3_close(db);

Beachten Sie auch, dass einige Funktionen (sqlite3_open_v2(), sqlite3_prepare_v2()) erscheinen auf den späteren SQLite-Versionen (ich nehme an 3.5.x und höher).

Sie möchten die Aussage sqlite_prepare_v2() vorzukompilieren, und dann das Blob binden sich mit der sqlite3_bind_blob(). Beachten Sie, dass die Aussage, die Sie binden in wird INSERT INTO Tabelle VALUES (?) .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top