Domanda

Sto lavorando allo sviluppo di un'API C ++ che utilizza plug-in personalizzati per interfacciarsi con diversi motori di database utilizzando le loro API e SQL specifici sintassi.

Attualmente, sto cercando di trovare un modo per inserire BLOB, ma poiché NULL è carattere finale in C / C ++, il BLOB viene troncato durante la costruzione la stringa di query INSERT INTO . Finora ho lavorato con

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

Mi aspetto che, se è possibile farlo nella console interattiva SQLite3, dovrebbe essere possibile costruire la stringa di query con caratteri NULL correttamente sottoposti a escape. Forse c'è un modo per farlo con SQL standard supportato anche dalla sintassi SQLite SQL?

Sicuramente qualcuno deve aver affrontato la stessa situazione prima. Ho cercato su Google e ho trovato delle risposte ma ero in altri linguaggi di programmazione (Python).

Grazie in anticipo per il tuo feedback.

È stato utile?

Soluzione

Ti consigliamo di utilizzare questa funzione con un'istruzione preparata.

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

In C / C ++, il modo standard di trattare i NULL nelle stringhe è di memorizzare l'inizio della stringa e una lunghezza, oppure memorizzare un puntatore all'inizio di una stringa e uno alla fine della stringa.

/ p>

Altri suggerimenti

Grazie ancora a tutti per il feedback. Questa volta sto segnalando come ho risolto il problema con l'aiuto delle indicazioni fornite qui. Speriamo che questo possa aiutare gli altri in futuro.

Come suggerito dai primi tre poster, ho usato dichiarazioni preparate, inoltre perché ero anche interessato a ottenere i tipi di dati delle colonne, e un semplice sqlite3_get_table () non avrebbe funzionato.

Dopo aver preparato l'istruzione SQL sotto forma della seguente stringa costante:

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

rimane il vincolante dei valori corrispondenti. Questo viene fatto emettendo tante sqlite3_bind_blob () quante colonne. (Ho anche fatto ricorso a sqlite3_bind_text () per altri tipi di dati "semplici" perché l'API su cui sto lavorando può tradurre numeri interi / doppi / ecc. In una stringa). Quindi:

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

Nota anche che alcune funzioni ( sqlite3_open_v2 () , sqlite3_prepare_v2 () ) appaiono nelle versioni successive di SQLite (suppongo 3.5.xe successive).

Si desidera precompilare l'istruzione sqlite_prepare_v2 () , quindi associare il BLOB usando sqlite3_bind_blob () . Nota che l'istruzione a cui ti associ sarà INSERISCI nella tabella VALORI (?) .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top