Pergunta

Eu estou trabalhando no desenvolvimento de API de C ++ que usa plugins customizados a interface com diferentes bancos de dados usando suas APIs e SQL específica sintaxe.

Atualmente, estou tentando encontrar uma maneira de inserir BLOBs, mas desde NULL é o caráter de terminação em C / C ++, o BLOB fica truncado ao construir INSERT INTO string de consulta. Até agora, eu tenho trabalhado com

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

Espero que, se for de todo possível fazê-lo no console interativo SQLite3, deve ser possível construir a string de consulta com personagens NULL adequadamente escaparam. Talvez haja uma maneira de fazer isso com o SQL padrão, que também é suportado pelo SQLite SQL sintaxe?

Certamente alguém deve ter enfrentado a mesma situação antes. Eu pesquisei e encontrei algumas respostas, mas estavam em outras linguagens de programação (Python).

Agradecemos antecipadamente para o seu feedback.

Foi útil?

Solução

Você vai querer usar esta função com uma declaração preparada.

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

C / C ++, a maneira padrão de lidar com nulos em cadeias, quer seja para armazenar o início da cadeia e um comprimento, ou armazenar um apontador para o início de uma cadeia e um para o final da cadeia.

Outras dicas

Obrigado a todos novamente por seu feedback. Desta vez eu estou relatando como eu resolvi o problema com a ajuda das indicações fornecidas aqui. Esperemos que isto irá ajudar os outros no futuro.

Como sugerido pelos três primeiros cartazes, fiz uso elaborou demonstrações -. Além disso, porque eu também estava interessado na obtenção de tipos de dados das colunas, e uma sqlite3_get_table() simples não faria

Depois de preparar a instrução SQL na forma do seguinte string constante:

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

permanece o de ligação dos valores correspondentes. Isto é feito através da emissão de tantas chamadas sqlite3_bind_blob() como as colunas. (Eu também recorreu a sqlite3_bind_text() para outros tipos de dados "simples" porque a API que estou trabalhando pode traduzir números inteiros / duplos / etc para uma string). Assim:

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

Note também que algumas funções (sqlite3_open_v2(), sqlite3_prepare_v2()) aparecem nas versões mais tarde SQLite (suponho 3.5.x e posterior).

Você quer pré-compilar o sqlite_prepare_v2() declaração, e depois ligar o blob em usar sqlite3_bind_blob(). Note-se que a declaração que ligam in será inserir valores da tabela (?) .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top