Question

Je travaille au développement d'une API C ++ qui utilise des plugins conçus sur mesure d'interfacer avec différents moteurs de base de données en utilisant leurs API et SQL spécifique syntaxe.

Actuellement, j'essaie de trouver un moyen d'insérer des BLOB, mais depuis NULL , le caractère final en C / C ++, le BLOB devient tronqué lors de la construction la chaîne de requête INSERT INTO . Jusqu'à présent, j'ai travaillé avec

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

J'espère que s'il est possible de le faire dans la console interactive SQLite3, il devrait être possible de construire la chaîne de requête avec des caractères NULL correctement échappés. Peut-être y a-t-il un moyen de faire cela avec du SQL standard qui est également supporté par la syntaxe SQLite SQL?

Il est certain que quelqu'un a déjà dû faire face à la même situation. J'ai cherché sur Google et trouvé des réponses, mais dans d'autres langages de programmation (Python).

Merci d'avance pour vos commentaires.

Était-ce utile?

La solution

Vous voudrez utiliser cette fonction avec une instruction préparée.

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

En C / C ++, la manière habituelle de traiter les valeurs NULL dans les chaînes consiste à stocker le début de la chaîne et une longueur, ou à stocker un pointeur au début de la chaîne et un à la fin de la chaîne. / p>

Autres conseils

Merci encore à tous pour vos commentaires. Cette fois, je rapporte comment j'ai résolu le problème à l'aide des indications fournies ici. J'espère que cela aidera les autres à l'avenir.

Comme suggéré par les trois premières affiches, j’ai utilisé des déclarations préparées & # 8212; En outre, je souhaitais également obtenir les types de données des colonnes et qu'un simple sqlite3_get_table () ne suffirait pas.

Après avoir préparé l'instruction SQL sous la forme de la chaîne constante suivante:

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

il reste la liaison des valeurs correspondantes. Cela est fait en émettant autant d'appels sqlite3_bind_blob () que les colonnes. (J'ai également eu recours à sqlite3_bind_text () pour d'autres types de données "simples", car l'API sur laquelle je travaille peut traduire des entiers / doubles / etc en une chaîne). Donc:

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

Notez également que certaines fonctions ( sqlite3_open_v2 () , sqlite3_prepare_v2 () ) apparaissent dans les versions ultérieures de SQLite (3.5.x et versions ultérieures).

Vous souhaitez précompiler l'instruction sqlite_prepare_v2 () , puis lier le blob en utilisant sqlite3_bind_blob () . Notez que l'instruction à laquelle vous lierz sera INSERT INTO table VALUES (?) .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top