2009-01-01 2 views
8

Я работаю над разработкой C++ API, который использует настраиваемые плагины для взаимодействия с различными ядрами баз данных с использованием их API и специфического синтаксиса SQL .SQLite3: Вставить BLOB с NULL-символами в C++

В настоящее время я пытаюсь найти способ вставки BLOB-, но так как NULL является оконечный символ в C/C++, то BLOB становится усеченным при построении INSERT INTO строки запроса. До сих пор, я работал с

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

я ожидаю, что, если это вообще возможно сделать это в интерактивной консоли SQLite3, она должна быть возможность построить строку запроса с правильно спасся NULL символов. Может быть, есть способ сделать это со стандартным SQL, который также поддерживается синтаксисом SQLite SQL?

Несомненно, кто-то должен был столкнуться с такой же ситуацией раньше. Я googled и нашел ответы, но был на других языках программирования (Python).

Заранее благодарю вас за отзыв.

+0

[This] (http://www.sqlite.org/c3ref/bind_blob.html), похоже, перечисляет все необходимые вам функции. – zvrba

ответ

8

Вы хотите использовать эту функцию с помощью подготовленного оператора.

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

В C/C++, стандартный способ обращения с значением NULL в строках является либо сохранить начало строки и длину, или хранить указатель на начало строки и одного конца Струна.

1

Вы хотите предварительно скомпоновать заявление sqlite_prepare_v2(), а затем привязать blob с помощью sqlite3_bind_blob(). Обратите внимание, что в заявлении, которое вы связываете, будет INSERT INTO table VALUES (?).

+0

Я не уверен в этом, но у меня есть сингл "?" Работодатель работает? Или необходимо иметь столько, сколько количество полей таблицы? – jbatista

+1

Да, вам нужно будет совместить количество полей, если вы сделаете это так. –

9

Еще раз спасибо за отзыв. На этот раз я сообщаю, как я решил проблему с помощью приведенных здесь указаний. Надеюсь, это поможет другим в будущем.

Как было предложено в первых трех плакатах, я также использовал подготовленные заявления —, потому что я также интересовался получением типов данных столбцов, и простой sqlite3_get_table() не сделал бы.

После подготовки оператора SQL в виде следующей постоянной строки:

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

он остается связывания соответствующих величин. Это делается путем выпуска в качестве столбцов количества звонков sqlite3_bind_blob(). (Я также прибегал к sqlite3_bind_text() для других «простых» типов данных, потому что API, над которым я работаю, может переводить целые числа/удваивания/etc в строку). Итак:

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

Следует также отметить, что некоторые функции (sqlite3_open_v2(), sqlite3_prepare_v2()) появляются на более поздних версиях SQLite (я полагаю, 3.5.x и более поздних версий).

+1

Отсутствует slqite3_close (db) – kibab

+0

@kibab Спасибо, исправил его. (BTW, вы бы хотели улучшить его самостоятельно.) – jbatista

+0

Я не знал, что могу редактировать другие сообщения :) Спасибо, хорошо знать. – kibab

Смежные вопросы