考虑:
int user_id = 0x01; //dummy
int size_id = 0x01; //dummy
sqlite3_stmt *stmt;
sqlite3 *db;
int rc = sqlite3_open("path_to_database.db", &db);
if( rc != SQLITE_OK )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return -1;
}
rc = sqlite3_prepare_v2(db, "SELECT id, type, time_registered"
" from myTestTable"
" where user = ? and size = ?", -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
throw std::string(sqlite3_errmsg(db));
sqlite3_finalize(stmt);
return -1;
}
rc = sqlite3_bind_int(stmt, 1, user_id);
if (rc != SQLITE_OK)
{
std::string errmsg(sqlite3_errmsg(db));
sqlite3_finalize(stmt);
throw errmsg;
return -1;
}
rc = sqlite3_bind_int(stmt, 2, size_id);
if (rc != SQLITE_OK)
{
std::string errmsg(sqlite3_errmsg(db));
sqlite3_finalize(stmt);
throw errmsg;
return -1;
}
[...]
这确实有效,但似乎对用户不友好。我可以使用snprintf代替绑定来准备语句,但是我会失去安全性(即使我不应该对本地数据库进行注入攻击)。
是否有更好的方法使用sqlite3_bind_TYPES绑定同一类型(如果可能的话)的一个语句中的多个值?
答案 0 :(得分:0)
您可以使用像SQLiteCpp这样的c ++包装器。如果您不喜欢它,则在github页面的底部有一个列表。
如果您更喜欢使用c接口,则可以反转bind语句的逻辑。这至少会使代码有些混乱。
int rc = sqlite3_open("path_to_database.db", &db);
if( rc != SQLITE_OK )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return -1;
}
rc = sqlite3_prepare_v2(db, "SELECT id, type, time_registered"
" from myTestTable"
" where user = ? and size = ?", -1, &stmt, NULL);
if (rc == SQLITE_OK)
rc = sqlite3_bind_int(stmt, 1, user_id);
if (rc == SQLITE_OK)
rc = sqlite3_bind_int(stmt, 2, size_id);
if (rc != SQLITE_OK)
{
throw std::string(sqlite3_errmsg(db));
sqlite3_finalize(stmt);
return -1;
}
[...]
迈克