如何使用一个结果集处理程序消除多个类似的sql查询
How to eliminate multiple similar sql queries with one resultset handler?
我有一些类似的sql查询,所有选择的字段都是相同的,只是条件不同。结果集处理程序也是一样的。我使用sqlite3和sqlite_modern_cpp。
下面是两个类似的函数(还有其他几个):QVariantMap getItemById(int id) {
QVariantMap map;
database db(dbfile);
db << "select id,name,price,qty from items where id=?"
<< id
>> [&] (int id, std::string name, double price, int qty) {
map.insert("id", id);
map.insert("name", QString::fromStdString(name));
map.insert("price", price);
map.insert("qty", qty);
};
return map;
}
QVariantMap getItemByCatAndSeq(int cat, int seq) {
QVariantMap map;
database db(dbfile);
db << "select id,name,price,qty from items where cat=? and seq=?"
<< cat << seq
>> [&] (int id, std::string name, double price, int qty) {
map.insert("id", id);
map.insert("name", QString::fromStdString(name));
map.insert("price", price);
map.insert("qty", qty);
};
return map;
}
您看,查询中的所有字段都是"id,name,price,qty",结果集处理程序也相同。
一个结果集处理程序应该就足够了,但是我必须在每个函数中复制粘贴相同的代码。此外,所选字段的名称和顺序必须与参数resultset handler——lambda function匹配。
如何消除这种重复的代码?有没有更好的解决办法?提前谢谢。
编辑:我尝试了函子方法,如下所示:
struct ItemResultHandler {
explicit ItemResultHandler(QVariantMap& map_) : map(map_) {}
void operator() ( int id, std::string name, double price, int qty ) {
map.insert("id", id);
map.insert("name", QString::fromStdString(name));
map.insert("price", price);
map.insert("qty", qty);
}
QVariantMap& map;
};
上述两个类似的函数之一将被修改为:
QVariantMap getItemById(int id) {
QVariantMap map;
database db(dbfile);
db << "select id,name,price,qty from items where id=?"
<< id
>> ItemResultHandler(map);
return map;
}
但是它有编译错误:
../../myapp/src/utility/function_traits.h:12: error: type 'void (ItemResultHandler::*)(std::__1::basic_string<char>, std::__1::basic_string<char>, int, int)' cannot be used prior to '::' because it has no members
decltype(&Function::operator())
^
../../myapp/src/sqlite_modern_cpp.h:218: error: incomplete definition of type 'sqlite::utility::function_traits<ItemResultHandler>'
binder<traits::arity>::run(*this, func);
~~~~~~^~
映射我们处理的所有不同结果类型是一个问题。因此,模板变得有点复杂,看起来它不处理这种情况。
下面是一个如何使用类型扩展的示例。
// The thing you want
struct Item {
int id;
string name;
double price;
int qty;
};
// to get it back we need to give a deserialization method:
namespace sqlite {
template<> void get_col_from_db(database_binder& db, int inx, ::Item*& ret) { // specify the type it will be used on, a pointer is necessary if you’re type has no default constructor. Otherwise a object ref does the job too.
ret = new Item();
get_col_from_db(db, inx++, ret->id);
get_col_from_db(db, inx++, ret->name);
get_col_from_db(db, inx++, ret->price);
get_col_from_db(db, inx++, ret->qty);
}
}
{// usage
Item* item;
db << "select val,name,price,qty from test" >> item;
std::cout << item->name;
delete item;
}
但这是丑陋的,绝对需要改变,我将摆脱这种指针混乱在下一个版本。
然而,有一个更短的版本,只需将你的函子以这种方式转换为lambda,将你的QMap替换为我的结构体:
auto ItemResultHandler = [](Item& item) -> std::function<void(int, std::string , double , int )> {
return [&item](int id, std::string name, double price, int qty) mutable {
item.id = id;
item.name = name;
item.price = price;
item.qty = qty;
};
};
,就像这样使用:
Item item;
db << "select val,name,price,qty from test" >> ItemResultHandler(item);
相关文章:
- 为 Sql 服务器实现 odbc 包装器.将数据库数据读取为字符或要求驱动程序将数据转换为 C 类型
- 如何在将Visual Studio C++控制台应用程序连接到Microsoft SQL Server时修复"
- SQL Server-未找到数据源名称,也未指定默认驱动程序
- 连接到MS SQL的程序类型超出范围
- 应用程序在 C++ QT 上执行 sql 后崩溃
- QT 5.8 SQL连接错误:Windows 10上未加载QMYSQL驱动程序
- QT SQL MySQL驱动程序未在运输中加载
- 面向C++程序员的 SQL 简介
- 如何从C ++控制台程序连接到MS SQL SERVER
- PostgreSQL 的替代方案,用于 C/C++ 应用程序中的嵌入式 SQL 数据库
- sql控制台应用程序中的MFC库
- 从C++应用程序向SQL表中的整数列发送null值
- C++程序中存在SQL查询语法错误,但可在MySQL工作台中使用
- SQL SP在SSMS中正常工作,但在VC++应用程序中失败
- 在Xubuntu上使用SOCI(sql包装器),简单的程序在编译时失败
- Sql Express SQL 驱动程序连接C++
- 程序的本地/专用 sql 数据库
- 由触发器调用的 MS SQL XP 更改 C++ 文件日期戳,以允许刷新表单应用程序 vb.net
- 在正在运行的C++程序中自动创建 SQL Server 数据库
- 为什么从客户端应用程序调用 PL/SQL 调用 SQL 引擎