パフォーマンス上の利点を得るためにプリペアド ステートメントを使用する必要があるアプリケーションを作成していますが、何百ものプリペアド ステートメントではないにしても数十ものプリペアド ステートメントを含むアプリケーションがある場合、混乱したグローバル コードにならないようにどのように管理すればよいのでしょうか。 ? コンストラクター/関数内のすべてのステートメントを、それらが使用されている場所とはまったく異なる場所で準備する必要がありますか?
クエリは実際に使用している場所にあるので sqlite_exec を使用するのは良いことですが、準備されたステートメントを使用すると、コードのまったく異なる領域にそれらを配置することになり、関数でどの変数をバインドする必要があるかについて曖昧/混乱します。実際にそれらを使用します。
具体的には、現在、プライベート変数を持つデータベースシングルトンがあります。
sqlite3_stmt *insertPacketCount;
sqlite3_stmt *insertPortContacted;
sqlite3_stmt *insertPacketSize;
sqlite3_stmt *computePacketSizeVariance;
...
コンストラクターが sqlite3_prepare_v2 を何十回も呼び出すと、
// Set up all our prepared queries
res = sqlite3_prepare_v2(db,
"INSERT OR IGNORE INTO packet_counts VALUES(?1, ?2, ?3, 1);",
-1, &insertPacketCount, NULL);
expectReturnValueAndFail(SQLITE_OK);
...
そして、それらを他の場所で使用する実際の関数は、
void Database::IncrementPacketCount(std::string ip, std::string interface, std::string type, uint64_t increment)
{
int res;
res = sqlite3_bind_text(incrementPacketCount, 1, ip.c_str(), -1, SQLITE_STATIC);
expectReturnValue(SQLITE_OK);
res = sqlite3_bind_text(incrementPacketCount, 2, interface.c_str(), -1, SQLITE_STATIC);
expectReturnValue(SQLITE_OK);
res = sqlite3_bind_text(incrementPacketCount, 3, type.c_str(), -1, SQLITE_STATIC);
expectReturnValue(SQLITE_OK);
res = sqlite3_bind_int(incrementPacketCount, 4, increment);
expectReturnValue(SQLITE_OK);
res = sqlite3_step(incrementPacketCount);
expectReturnValue(SQLITE_DONE);
res = sqlite3_reset(incrementPacketCount);
expectReturnValue(SQLITE_OK);
}
準備されたクエリを使用する関数の内部では、バインド インデックスが何であるかを把握するために準備ステートメントに戻るのが面倒です。
これがあいまいな場合は申し訳ありませんが、パフォーマンス/安全性を犠牲にすることなくこの種のものを整理するためのライブラリまたはメソッドはありますか (文字列を追加して sqlite_exec を呼び出すなど)?