ADO数据库编程入门 liandong(原作)[5]

[入库:2005年8月18日] [更新:2007年3月27日]

本文简介:选择自 westerly 的 blog

 modify},

 #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("au_lname")->properties->getitem("optimize")->value = true;
rs1->sort = "au_lname asc"
rs1->filter = "phone like 阏 5*&"

rs1->movefirst();
while (variant_false == rs1->endoffile)
{
 printf("name: %s\t %s\tphone: %s\n", 
  (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("h:\\aaa.jpg",cfile::moderead);
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<uisread;index++)         
 {
  if(failed(safearrayputelement(psa,&index,&bval[index])))
  ::messagebox(null,"啊,又出毛病了。","提示",mb_ok | mb_iconwarning);
 }
 varchunk.vt = vt_array|vt_ui1;
 varchunk.parray = psa;
 try{
  m_precordset->fields->getitem("photo")->appendchunk(varchunk);
 }
 catch (_com_error &e)
 {
  cstring str=(char*)e.description();
  ::messagebox(null,str+"\n又出毛病了。","提示",mb_ok | mb_iconwarning);
 }
 ::variantclear(&varchunk);
 ::safearraydestroydata( psa);
 if(uisread<chunksize)break;
}//while(1) 
f.close();

//从数据库读一张照片:
cfile f;
f.open("h:\\bbb.jpg",cfile::modewrite|cfile::modecreate);
long lphotosize = m_precordset->fields->item["photo"]->actualsize; 
long lisread=0;

_variant_t varchunk;
byte buf[chunksize];
while(lphotosize>0)
{
 lisread=lphotosize>=chunksize? chunksize:lphotosize;
 varchunk = m_precordset->fields->
                  item["photo"]->getchunk(lisread);
 for(long index=0;index<lisread;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.

本文关键:,ADO,
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top