📄 ado数据库编程入门.htm
字号:
{<br>
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 : ""));<br>
<br>
if (rs.lphoneStatus == adFldOK)<br>
strcpy(rs.m_szphone, "777");<br>
<br>
TESTHR(picRs->Update(&rs)); // Add change to the batch<br>
Rs1->MoveNext();<br>
}<br>
Rs1->Filter = (long) adFilterNone;<br>
......<br>
if (picRs) picRs->Release();<br>
Rs1->Close();<br>
pConn->Close();</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
只要字段的状态是adFldOK,就可以访问。如果修改了字段,不要忘了先调用picRs的Update(注意不是Recordset的Update),然后才关闭,也不要忘了释放picRs(即picRs->Release();)。<br>
<br>
(4). 此时还可以用IADORecordBinding接口添加新纪录<br>
<br>
</font>
</font>
<font color="#99CCFF" face="宋体" size="2">if(FAILED(picRs->AddNew(&rs)))<br>
......</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
11. 访问长数据<br>
在Microsoft SQL中的长数据包括text、image等这样长类型的数据,作为二进制字节来对待。<br>
可以用Field对象的GetChunk和AppendChunk方法来访问。每次可以读出或写入全部数据的一部分,它会记住上次访问的位置。但是如果中间访问了别的字段后,就又得从头来了。<br>
请看下面的例子:<br>
//写入一张照片到数据库:<br>
<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
VARIANT varChunk;<br>
SAFEARRAY *psa;<br>
SAFEARRAYBOUND rgsabound[1];<br>
//VT_ARRAY | VT_UI1<br>
<br>
CFile f("h:\\aaa.jpg",CFile::modeRead);<br>
BYTE bVal[ChunkSize+1];<br>
UINT uIsRead=0;<br>
<br>
//Create a safe array to store the array of BYTES <br>
while(1)<br>
{<br>
uIsRead=f.Read(bVal,ChunkSize);<br>
if(uIsRead==0)<br>
break;<br>
rgsabound[0].cElements =uIsRead;<br>
rgsabound[0].lLbound = 0;<br>
psa = SafeArrayCreate(VT_UI1,1,rgsabound);<br>
<br>
for(long index=0;index<uIsRead;index++)<br>
{<br>
if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))<br>
::MessageBox(NULL,"啊,又出毛病了。","提示",MB_OK | MB_ICONWARNING);<br>
}<br>
<br>
varChunk.vt = VT_ARRAY|VT_UI1;<br>
varChunk.parray = psa;<br>
try<br>
{<br>
m_pRecordset->Fields->GetItem("photo")->AppendChunk(varChunk);<br>
}<br>
catch (_com_error &e)<br>
{<br>
CString str=(char*)e.Description();<br>
::MessageBox(NULL,str+"\n又出毛病了。","提示",MB_OK | MB_ICONWARNING);<br>
}<br>
<br>
::VariantClear(&varChunk);<br>
::SafeArrayDestroyData( psa);<br>
if(uIsRead<ChunkSize)<br>
break;<br>
}//while(1) <br>
<br>
f.Close();<br>
<br>
//从数据库读一张照片:<br>
CFile f;<br>
f.Open("h:\\bbb.jpg",CFile::modeWrite|CFile::modeCreate);<br>
long lPhotoSize = m_pRecordset->Fields->Item["photo"]->ActualSize; <br>
long lIsRead=0;<br>
_variant_t varChunk;<br>
BYTE buf[ChunkSize];<br>
<br>
while(lPhotoSize>0)<br>
{<br>
lIsRead=lPhotoSize>=ChunkSize? ChunkSize:lPhotoSize;<br>
varChunk = m_pRecordset->Fields->Item["photo"]->GetChunk(lIsRead);<br>
<br>
for(long index=0;index<lIsRead;index++) <br>
{ <br>
::SafeArrayGetElement(varChunk.parray,&index,buf+index); <br>
}<br>
f.Write(buf,lIsRead);<br>
lPhotoSize-=lIsRead;<br>
}//while()<br>
<br>
f.Close();</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
12. 使用SafeArray问题<br>
学会使用SafeArray也是很重要的,因为在ADO编程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray。实质上SafeArray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。SafeArray也并不单独使用,而是将其再包装到VARIANT类型的变量中,然后才作为参数传送出去。在VARIANT的vt成员的值如果包含VT_ARRAY|...,那么它所封装的就是一个SafeArray,它的parray成员即是指向SafeArray的指针。SafeArray中元素的类型可以是VARIANT能封装的任何类型,包括VARIANT类型本身。 <br>
使用SafeArray的具体步骤:<br>
<br>
方法一:<br>
包装一个SafeArray:<br>
<br>
(1). 定义变量,如:<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
VARIANT varChunk;<br>
SAFEARRAY *psa;<br>
SAFEARRAYBOUND rgsabound[1];<br>
</font>
<font face="Arial">
<font face="Arial" size="2">
<br>
(2). 创建SafeArray描述符:<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
uIsRead=f.Read(bVal,ChunkSize);//read array from a file.<br>
if(uIsRead==0)<br>
break;<br>
rgsabound[0].cElements =uIsRead;<br>
rgsabound[0].lLbound = 0;<br>
psa = SafeArrayCreate(VT_UI1,1,rgsabound);</font><font face="Arial"><font face="Arial" size="2"><font color="#99CCFF"><br>
</font>
<br>
(3). 放置数据元素到SafeArray:<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
for(long index=0;index<uIsRead;index++) <br>
{<br>
if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))<br>
::MessageBox(NULL,"出毛病了。","提示",MB_OK | MB_ICONWARNING);<br>
}</font><font face="Arial"><font face="Arial" size="2"><br>
一个一个地放,挺麻烦的。<br>
<br>
(4). 封装到VARIANT内:<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
varChunk.vt = VT_ARRAY|VT_UI1;<br>
varChunk.parray = psa;</font><font face="Arial"><font face="Arial" size="2"><br>
这样就可以将varChunk作为参数传送出去了。<br>
读取SafeArray中的数据的步骤:<br>
<br>
(1). 用SafeArrayGetElement一个一个地读<br>
<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
BYTE buf[lIsRead];<br>
for(long index=0;index<lIsRead;index++) <br>
{ <br>
::SafeArrayGetElement(varChunk.parray,&index,buf+index); <br>
}</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
就读到缓冲区buf里了。<br>
<br>
方法二:<br>
使用SafeArrayAccessData直接读写SafeArray的缓冲区:<br>
<br>
(1). 读缓冲区:<br>
</font>
</font>
<font color="#99CCFF" face="宋体" size="2">BYTE *buf;<br>
SafeArrayAccessData(varChunk.parray, (void **)&buf);<br>
f.Write(buf,lIsRead);<br>
SafeArrayUnaccessData(varChunk.parray);</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
(2). 写缓冲区:<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
BYTE *buf;<br>
::SafeArrayAccessData(psa, (void **)&buf);<br>
for(long index=0;index<uIsRead;index++) <br>
{<br>
buf[index]=bVal[index]; <br>
}<br>
::SafeArrayUnaccessData(psa);<br>
varChunk.vt = VT_ARRAY|VT_UI1;<br>
varChunk.parray = psa;<br>
</font>
<font face="Arial">
<font face="Arial" size="2">这种方法读写SafeArray都可以,它直接操纵SafeArray的数据缓冲区,比用SafeArrayGetElement和SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData(psa),否则会出错的。<br>
<br>
13. 使用书签( bookmark )<br>
书签可以唯一标识记录集中的一个记录,用于快速地将当前记录移回到已访问过的记录,以及进行过滤等等。Provider会自动为记录集中的每一条记录产生一个书签,我们只需要使用它就行了。我们不能试图显示、修改或比较书签。ADO用记录集的Bookmark属性表示当前记录的书签。<br>
用法步骤:<br>
<br>
(1). 建立一个VARIANT类型的变量<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
_variant_t VarBookmark;</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
(2). 将当前记录的书签值存入该变量<br>
也就是记录集的Bookmark属性的当前值。<br>
</font>
</font>
<font face="宋体" size="2" color="#99CCFF">
VarBookmark = rst->Bookmark;</font><font face="Arial"><font face="Arial" size="2"><br>
<br>
(3). 返回到先前的记录<br>
将保存的书签值设置到记录集的书签属性中:<br>
<br>
</font>
</font>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -