8

カスタム設計されたプラグインを使用して、API と特定の SQL 構文を使用してさまざまなデータベース エンジンとやり取りする C++ API の開発に取り組んでいます。

現在、BLOB を挿入する方法を見つけようとしていますがNULL、C/C++ では終端文字であるため、INSERT INTOクエリ文字列を作成するときに BLOB が切り捨てられます。これまで一緒に仕事をしてきた

//...
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です。おそらく、SQLite SQL 構文でもサポートされている標準 SQL でこれを行う方法はありますか?

きっと誰かが同じ状況に直面したことがあるはずです。私はグーグルでいくつかの答えを見つけましたが、他のプログラミング言語(Python)でした。

フィードバックをお寄せいただきありがとうございます。

4

3 に答える 3

10

フィードバックをお寄せいただきありがとうございます。今回は、ここで提供された指示を使用して問題を解決した方法を報告します。うまくいけば、これは将来他の人に役立つでしょう。

最初の 3 人の投稿者が示唆したように、準備済みステートメントを使用しました。さらに、列のデータ型を取得することにも関心があり、単純なステートメントではうまくいきsqlite3_get_table()ませんでした。

次の定数文字列の形式で SQL ステートメントを準備した後:

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

対応する値のバインディングのままです。sqlite3_bind_blob()これは、列と同じ数の呼び出しを発行することによって行われます。sqlite3_bind_text()(私が取り組んでいるAPIは整数/倍精度/その他を文字列に変換できるため、他の「単純な」データ型にも頼りました)。そう:

#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
/* ... */
void* blobvalue[4] = { NULL, NULL, NULL, NULL };
int blobsize[4] = { 0, 0, 0, 0 };
const char* tail = NULL;
const char* sql = "INSERT INTO tabl VALUES(?,?,?,?)";
sqlite3_stmt* stmt = NULL;
sqlite3* db = NULL;
/* ... */
sqlite3_open("sqlite.db", &db);
sqlite3_prepare_v2(db,
                   sql, strlen(sql) + 1,
                   &stmt, &tail);
for(unsigned 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 以降と思われます) に表示されることにも注意してください。

tablファイル内のSQLiteテーブルはsqlite.db(たとえば)で作成できます

CREATE TABLE tabl(a TEXT PRIMARY KEY, b TEXT, c TEXT, d TEXT);
于 2009-01-02T22:08:41.977 に答える
9

この関数は、準備されたステートメントで使用する必要があります。

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

C/C++ では、文字列内の NULL を処理する標準的な方法は、文字列の先頭と長さを格納するか、文字列の先頭と文字列の末尾へのポインターを格納することです。

于 2009-01-02T02:38:13.817 に答える
1

ステートメントをプリコンパイルしてからsqlite_prepare_v2()、BLOB を using にバインドしsqlite3_bind_blob()ます。バインドするステートメントはINSERT INTO table VALUES (?)になることに注意してください。

于 2009-01-01T12:57:58.993 に答える