SQLite3:Вставить большой двоичный объект с нулевыми символами в C ++

StackOverflow https://stackoverflow.com/questions/404879

  •  03-07-2019
  •  | 
  •  

Вопрос

Я работаю над разработкой 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().Обратите внимание, что оператор, который вы привяжете, будет следующим ВСТАВИТЬ В таблицу ЗНАЧЕНИЯ (?).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top