代码修改内容如下:
- 修改CRule::GenerateQryCond函数,用于生成保存的当前主查询条件表达式.
- 修改单表和多表规则的Handle函数,获取更新的条件字段值.
- 增加CvtCharArrayValue函数,把通过ADO获取的_variant_t值转换为16进制串格式.
关于sybase timestamp字段的读取:
- 对应的ADO字段类型为:VT_ARRAY|VT_UI1 0x2011
- 使用GetChunk读sybase timestamp字段出“在此环境中不允许操作”错误.直接用GetFieldValue访问,然后用CvtCharArrayValue函数转换.
- 可以使用类似下面语句的方法作为查询条件: select * from tb_test1 where f1=0x0000000000002872
/// 根据给定的值生成主查询条件
int CRule::GenerateQryCond(string &qry_cond,const char *qry_value) {
assert(!this->qry_fld_.empty());
if (IsNumberType(this->qry_fld_type_))
qry_cond = LogMsg("%s%s%s",this->qry_fld_.c_str(),CExpr::GetTokenStr(this->qry_op_),qry_value);
else if (this->qry_fld_type_==FT_BLOB) { ///< 支持sybase的timestamp字段作为主查询条件字段
qry_cond = LogMsg("%s%s%s",this->qry_fld_.c_str(),CExpr::GetTokenStr(this->qry_op_),qry_value);
}
else { //if (IsCharType(this->qry_fld_type_)
qry_cond = LogMsg("%s%s'%s'",this->qry_fld_.c_str(),CExpr::GetTokenStr(this->qry_op_),qry_value);
}
return 0;
}
以下是单表和多表规则的Handle函数修改内容的相关部分.
int CSingleTableRule::Handle(string &sql,unsigned long &count);
int CMultiTableRule::Handle(string &sql,unsigned long &count);
if (filter_type_==1) {
if (!qry_fld2_.empty()) {
/// 读主查询过滤字段
_variant_t vtQryFld;
if (!prs->GetFieldValue(qry_fld2_.c_str(),vtQryFld)) {
result = -1;
break;
}
if (this->qry_fld_type_==FT_BLOB) { ///< 主查询字段为timestamp类型的情况
char *p = 0;
if (CvtCharArrayValue(vtQryFld,&p)) {
result = -1;
break;
}
sQryValue = p;
delete []p;
}
else
sQryValue = ExVariantToString(vtQryFld);
CvtCharArrayValue函数实现:
//
static const char hexdigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
//
int StrToHex(const char *buffer,int len,char **new_buffer) {
char *out = new char[2*len+3];
char *po = out;
strcpy(po,"0x",3);
po += 2;
const char *p = buffer;
char ch = *p;
int k = 0;
while(k<len) {
*po = hexdigits[(ch>>4)&0x0F];
po++;
*po = hexdigits[ch&0x0F];
po++;
ch = *++p;
k++;
}
*po = '\0';
*new_buffer = out;
return 0;
}
//
int CvtCharArrayValue(_variant_t val,char **out) {
if (val.vt!=(VT_ARRAY|VT_UI1))
return -1;
SAFEARRAY *psa = val.parray;
if (psa->cDims!=1)
return -1;
HRESULT hr;
LONG lLbound1,lUbound1;
hr = SafeArrayGetLBound(psa, 1, &lLbound1);
if(FAILED(hr))
return -1;
hr = SafeArrayGetUBound(psa, 1, &lUbound1);
if(FAILED(hr))
return -1;
int size = lUbound1-lLbound1+1;
char *buffer = new char[size];
for (int i=lLbound1;i<=lUbound1;i++) {
long ix = i;
HRESULT hr = SafeArrayGetElement(psa, &ix, &buffer[i]);
if(FAILED(hr)) {
delete []buffer;
return -1;
}
}
char *new_buffer = 0;
StrToHex(buffer,size,&new_buffer);
delete []buffer;
*out = new_buffer;
return 0;
}