SQLite3:Вставить большой двоичный объект с нулевыми символами в C ++
Вопрос
Я работаю над разработкой C ++ API, который использует специально разработанные плагины для взаимодействия с различными ядрами баз данных, используя их API и специфический синтаксис SQL .
В настоящее время я пытаюсь найти способ вставки больших двоичных объектов, но поскольку NULL
есть
конечные символы в C/C++, то шарик будет усе при создании
в ВСТАВИТЬ В строка запроса.До сих пор я работал с
//...
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, который также поддерживается синтаксисом SQL SQLite?
Наверняка кто-то уже сталкивался с подобной ситуацией раньше.Я погуглил и нашел несколько ответов, но они были на других языках программирования (Python).
Заранее благодарю вас за ваш отзыв.
Решение
Вы захотите использовать эту функцию с подготовленным оператором.
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
В C / C ++ стандартным способом обработки нулей в строках является либо сохранение начала строки и длины, либо сохранение указателя на начало строки и указателя на конец строки.
Другие советы
Еще раз благодарю вас всех за ваши отзывы.На этот раз я сообщаю, как я решил проблему с помощью приведенных здесь указаний.Надеюсь, это поможет другим в будущем.
Как было предложено на первых трех плакатах, я использовал подготовленные инструкции — дополнительно потому, что мне также было интересно получить типы данных столбцов и простой 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 и более поздних).
Вы хотите предварительно скомпилировать инструкцию sqlite_prepare_v2()
, а затем свяжите большой двоичный объект с помощью sqlite3_bind_blob()
.Обратите внимание, что оператор, который вы привяжете, будет следующим ВСТАВИТЬ В таблицу ЗНАЧЕНИЯ (?).