我正在编写一个需要使用准备好的语句来获得性能优势的应用程序,但我想知道当你的应用程序有几十个甚至数百个准备好的语句时,你如何管理它而不把它变成一团糟的全局代码? 您是否只需要在与使用它们的位置完全不同的地方准备构造函数/函数中的所有语句?
使用 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)?