由于工作需要,使用ADO查询数据库,然后后把查询记录序列化到内存病通过网络传输到另外机器以便反序列化为Recordset。
起先,使用MS提供的方式,需要IpersistStream、IStream、OleSaveToStream、OleLoadFromStream详情请看 这里。嗯,很好,MS给出的例子很完美的测试通过~
天有不测风云人有旦夕祸福,由于业务需要,必须在查询语句使用绑定变量的方式来查询数据库,而不是组合查询SQL语句。这种方式的好处是,见 这里。由于这种需求,就必须使用
心有不甘,就不停的调试(边调边试),不停的google
现在需要考虑下如果跨平台,如何解决数据集的序列化,采用什么方式好呢?这是一个值得考虑的问题!
起先,使用MS提供的方式,需要IpersistStream、IStream、OleSaveToStream、OleLoadFromStream详情请看 这里。嗯,很好,MS给出的例子很完美的测试通过~
天有不测风云人有旦夕祸福,由于业务需要,必须在查询语句使用绑定变量的方式来查询数据库,而不是组合查询SQL语句。这种方式的好处是,见 这里。由于这种需求,就必须使用
Command对象了(Command对象才有参数绑定功能)。示例见这里
然而,Command对象执行Execute方法后,返回结果Recordset不能进行序列化了,此时的Recordset对象是只读的,并不能修改其中属性。因此,在调用OleSaveToStream时返回错误("查询不支持接口”),呵呵,够诡异吧!!这位老兄和我经历的一模一样,猛击这里
心有不甘,就不停的调试(边调边试),不停的google
终于,终于被我发现了解决方案。由于Recordset支持从Command来Open,而Command是绑定变量的唯一途径,所以咯,结合Recorset的Open方法,终于把问题解决了,下面给出解决代码
_CommandPtr cmd;
cmd.CreateInstance("ADODB.Command");
cmd->ActiveConnection=pNode->pCn;
cmd->CommandType=adCmdText;
cmd->CommandText=vsSQLText;
CStrArrayEX sPara;
sPara.SplitWord(vsParaList,"\n");
// CreateParameter Append...
//Append(cmd->CreateParameter("",adDouble,adParamInput,20,(_variant_t)&sPara.GetWord(i)[1]));
_variant_t affect;
//_RecordsetPtr pRS = cmd->Execute(&affect, 0, adCmdText);
_RecordsetPtr pRS;
pRS.CreateInstance(__uuidof(Recordset));
pRS->CursorLocation = adUseClient;
pRS->CursorType = adOpenDynamic;
pRS->LockType = adLockBatchOptimistic;
pRS->Open((IDispatch*)cmd, vtMissing, adOpenStatic,adLockBatchOptimistic, -1);
IStreamPtr stream;
stream.CreateInstance(__uuidof(IStream));
std::vector<char> buf;
if( SaveRS(pRS, &stream) == S_OK &&
StreamToMem(stream, buf) )
现在需要考虑下如果跨平台,如何解决数据集的序列化,采用什么方式好呢?这是一个值得考虑的问题!