查询一个列表,每个列表项有对应的一组明细记录(这里称为含明细列表).这是开发过程中常见的应用场景.如查询订单列表,同时返回每个订单的明细。
umx协议支持CRowset的列是一个CRowset(dtRowset类型),但umx.js未实现.
如果在服务端完成分拆,则返回多个CRowset.umx限制的最大行集数是65535.
一般方法是,1个CRowset表示列表内容,后面按出现在列表CRowset的顺序依次跟随每个记录的明细CRowset.
一种实现方法是先查询列表,然后对查询结果的每条记录对应的明细逐一查询。
假设一次查询页的大小为20条.则需要查询数据库21次。
循环是影响性能的常见原因.
可以对此进行优化,明细查询一次完成.总共只进行2次查询.
实现的主要函数QueryToMsgEx定义和实现在CQQBase.h的CQQBasePlugin.
umx协议支持CRowset的列是一个CRowset(dtRowset类型),但umx.js未实现.
如果在服务端完成分拆,则返回多个CRowset.umx限制的最大行集数是65535.
一般方法是,1个CRowset表示列表内容,后面按出现在列表CRowset的顺序依次跟随每个记录的明细CRowset.
一种实现方法是先查询列表,然后对查询结果的每条记录对应的明细逐一查询。
假设一次查询页的大小为20条.则需要查询数据库21次。
循环是影响性能的常见原因.
可以对此进行优化,明细查询一次完成.总共只进行2次查询.
代码示例:
string strSql = ///< 查询订单列表sql.
int Ret = PagizeQueryToMsg(strSql,strOrderBy,pIn,pAns); ///< 执行列表查询,获得订单列表
CRowset* pRs = pAns->GetRowset(0);/// pRs是查询订单列表的CRowset
pRs->First();
vector<string> vs;
while(!pRs->IsEof()) {
string strSheetId = pRs->GetFieldValueByName("SheetID"); ///< 单据id
vs.push_back(strSheetId);
pRs->Next();
}
string in_str;
MergeString(vs,in_str);///< 合并成IN表达式
strSql = LogMsg("select sheetid,goodsid,qty from t_orderitem where sheetid in (%s) order by sheetid",in_str.c_str());
if (QueryToMsgEx(strSql,"SheetId",1,vs,pAns))
return -1;
实现的主要函数QueryToMsgEx定义和实现在CQQBase.h的CQQBasePlugin.
///< 函数:QueryToMsgEx
///< 根据key_fld把查询结果顺序保存到pMsg的行集中
///< 参数:
///< strSql: 查询SQL
///< key_fld:key字段名称
///< remove_key_fld:是否从行集中删除key字段
///< vs:对象key列表
///< pMsg:输出CRowset的消息对象
///< 返回值: 0:成功 -1:失败
int QueryToMsgEx(const string& strSql,const string &key_fld,bool remove_key_fld,vector<string> &vs,CMsg *pMsg,const string &strDbc="");
注意使用限制:
.必须有一个单一列的key.示例为SheetID
.明细查询必须包含key字段,并且必须按key排序. 如果协议定义不要求返回key,可以设置QueryToMsgEx的remove_key_fld参数为true.
实现是针对5210协议优化的.见CMpm::OnQueryPurchaseList方法.
实现QueryToMsgEx,在query_func.h中增加了2个公共导出函数:
int RecordsetFieldToRowset(CRecordset *prs,CRowset *rs) ///< 数据库查询记录集的字段转换到CRowset列信息
int RecordToRowset(CRecordset *prs,CRowset *rs) ///< 把查询记录转换为CRowset记录