#define END_ADO_BINDING宏的定义也在icrsint.h文件里:
#define END_ADO_BINDING() {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\\ return rgADOBindingEntries;} (2). 绑定
_RecordsetPtr Rs1;
IADORecordBinding *picRs=NULL; CCustomRs rs; ......
Rs1->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&picRs));
picRs->BindToRecordset(&rs);
派生出的类必须通过IADORecordBinding接口才能绑定,调用它的BindToRecordset方法就行了。
(3). rs中的变量即是当前记录字段的值
//Set sort and filter condition: // Step 4: Manipulate the data
Rs1->Fields->GetItem(\= true; Rs1->Sort = \
Rs1->Filter = \
Rs1->MoveFirst();
while (VARIANT_FALSE == Rs1->EndOfFile) {
printf(\
(rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : \(rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : \(rs.lphoneStatus == adFldOK ? rs.m_szphone : \if (rs.lphoneStatus == adFldOK) strcpy(rs.m_szphone, \
TESTHR(picRs->Update(&rs)); // Add change to the batch Rs1->MoveNext(); }
Rs1->Filter = (long) adFilterNone; ......
if (picRs) picRs->Release(); Rs1->Close(); pConn->Close();
只要字段的状态是adFldOK,就可以访问。如果修改了字段,不要忘了先调用picRs的Update(注意不是Recordset的Update),然后才关闭,也不要忘了释放picRs(即picRs->Release();)。
(4). 此时还可以用IADORecordBinding接口添加新纪录 if(FAILED(picRs->AddNew(&rs))) ......
11. 访问长数据
在Microsoft SQL中的长数据包括text、image等这样长类型的数据,作为二进制字节来对待。
可以用Field对象的GetChunk和AppendChunk方法来访问。每次可以读出或写入全部数据的一部分,它会记住上次访问的位置。但是如果中间访问了别的字段后,就又得从头来了。
请看下面的例子: //写入一张照片到数据库: VARIANT varChunk; SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];
//VT_ARRAY │ VT_UI1
CFile f(\BYTE bVal[ChunkSize+1]; UINT uIsRead=0;
//Create a safe array to store the array of BYTES while(1) {
uIsRead=f.Read(bVal,ChunkSize); if(uIsRead==0)break;
rgsabound[0].cElements =uIsRead; rgsabound[0].lLbound = 0;
psa = SafeArrayCreate(VT_UI1,1,rgsabound); for(long index=0;index if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index]))) ::MessageBox(NULL,\啊,又出毛病了。\提示\ } varChunk.vt = VT_ARRAY│VT_UI1; varChunk.parray = psa; try{ m_pRecordset->Fields->GetItem(\} catch (_com_error &e) { CString str=(char*)e.Description(); ::MessageBox(NULL,str+\又出毛病了。\提示\ } ::VariantClear(&varChunk); ::SafeArrayDestroyData( psa); if(uIsRead //从数据库读一张照片: CFile f; f.Open(\bbb.jpg\ long lPhotoSize = m_pRecordset->Fields->Item[\long lIsRead=0; _variant_t varChunk; BYTE buf[ChunkSize]; while(lPhotoSize>0) { lIsRead=lPhotoSize>=ChunkSize? ChunkSize:lPhotoSize; varChunk = m_pRecordset->Fields-> Item[\ for(long index=0;index ::SafeArrayGetElement(varChunk.parray,&index,buf+index); } f.Write(buf,lIsRead); lPhotoSize-=lIsRead; }//while() f.Close(); 12. 使用SafeArray问题 学会使用SafeArray也是很重要的,因为在ADO编程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray。实质上SafeArray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。SafeArray也并不单独使用,而是将其再包装到VARIANT类型的变量中,然后才作为参数传送出去。在VARIANT的vt成员的值如果包含VT_ARRAY│...,那么它所封装的就是一个SafeArray,它的parray成员即是指向SafeArray的指针。SafeArray中元素的类型可以是VARIANT能封装的任何类型,包括VARIANT类型本身。 使用SafeArray的具体步骤: 方法一: 包装一个SafeArray: (1). 定义变量,如: VARIANT varChunk; SAFEARRAY *psa; SAFEARRAYBOUND rgsabound[1]; (2). 创建SafeArray描述符: uIsRead=f.Read(bVal,ChunkSize);//read array from a file. if(uIsRead==0)break; rgsabound[0].cElements =uIsRead; rgsabound[0].lLbound = 0; psa = SafeArrayCreate(VT_UI1,1,rgsabound); (3). 放置数据元素到SafeArray: for(long index=0;index if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index]))) ::MessageBox(NULL,\出毛病了。\提示\ } 一个一个地放,挺麻烦的。 (4). 封装到VARIANT内: varChunk.vt = VT_ARRAY│VT_UI1; varChunk.parray = psa; 这样就可以将varChunk作为参数传送出去了。 读取SafeArray中的数据的步骤: (1). 用SafeArrayGetElement一个一个地读 BYTE buf[lIsRead]; for(long index=0;index ::SafeArrayGetElement(varChunk.parray,&index,buf+index); }
相关推荐: