﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-时间的痕迹-文章分类-ADO编程技术</title><link>http://www.cppblog.com/ivenher/category/317.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 13:02:27 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 13:02:27 GMT</pubDate><ttl>60</ttl><item><title>_variant_t  中VT_DECIMAL 问题</title><link>http://www.cppblog.com/ivenher/articles/16638.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Wed, 20 Dec 2006 03:24:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/16638.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/16638.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/16638.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/16638.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/16638.html</trackback:ping><description><![CDATA[_variant_t 数据类型与其他数据类型的转换比较麻烦，以前用的是从网上找来的一段代码，存在一些问题，后果很严重，害我以为出现灵异事件了。<br />原方法如下：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> VT_DECIMAL: <br />             {<br />                  </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> val </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> var.decVal.Lo32;<br />                                     <br />                    val </span><span style="COLOR: #000000">*=</span><span style="COLOR: #000000"> (var.decVal.sign </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">128</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> : </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br />                    val </span><span style="COLOR: #000000">/=</span><span style="COLOR: #000000"> pow(</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">, var.decVal.scale); <br />                    CString strFormat;<br />                    strFormat.Format(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, var.decVal.scale);<br />                    strFormat </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">strFormat</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br />                                         strValue.Format(strFormat, val);<br /><br />                                 </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br />             }</span></div><br /><br />转过多次没出什么事就认为这段代码可以用。结果问题就出在这段代码。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000"><br /><img id="Codehighlighter1_1_8_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1_8_Open_Text.style.display='none'; Codehighlighter1_1_8_Closed_Image.style.display='inline'; Codehighlighter1_1_8_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1_8_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1_8_Closed_Text.style.display='none'; Codehighlighter1_1_8_Open_Image.style.display='inline'; Codehighlighter1_1_8_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_1_8_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_1_8_Open_Text"><span style="COLOR: #808080">///</span><span style="COLOR: #008000">问题所在</span><span style="COLOR: #808080"></span></span><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> val </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> var.decVal.Lo32;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">应改为 </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> val</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">var.decVal.Lo64;</span></div><br />当数据较大时数据被截断，灵异事件就出现了。 <img src ="http://www.cppblog.com/ivenher/aggbug/16638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-12-20 11:24 <a href="http://www.cppblog.com/ivenher/articles/16638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>调用存储过程</title><link>http://www.cppblog.com/ivenher/articles/9655.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Mon, 10 Jul 2006 11:34:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/9655.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/9655.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/9655.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/9655.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/9655.html</trackback:ping><description><![CDATA[ ptrCmd-&gt;CommandText = "P_KS_ADDUSER";<br />  ptrCmd-&gt;CommandType = adCmdStoredProc;<br />  ptrCmd-&gt;Execute(NULL,NULL,adCmdStoredProc);<img src ="http://www.cppblog.com/ivenher/aggbug/9655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-07-10 19:34 <a href="http://www.cppblog.com/ivenher/articles/9655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual C++ ADO数据库编程入门（下）</title><link>http://www.cppblog.com/ivenher/articles/2294.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Fri, 30 Dec 2005 10:32:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2294.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2294.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2294.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2294.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2294.html</trackback:ping><description><![CDATA[<DIV class=postText>10、邦定数据<BR><BR>　　定义一个绑定类，将其成员变量绑定到一个指定的记录集，以方便于访问记录集的字段值。<BR><BR>　　(1). 从CADORecordBinding派生出一个类：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>class CCustomRs : public CADORecordBinding<BR>{<BR>BEGIN_ADO_BINDING(CCustomRs)<BR>ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname, <BR>sizeof(m_szau_fname), lau_fnameStatus, false)<BR>ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname, <BR>sizeof(m_szau_lname), lau_lnameStatus, false)<BR>ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_szphone, <BR>sizeof(m_szphone), lphoneStatus, true)<BR>END_ADO_BINDING()<BR><BR>public:<BR>CHAR m_szau_fname[22];<BR>ULONG lau_fnameStatus;<BR>CHAR m_szau_lname[42];<BR>ULONG lau_lnameStatus;<BR>CHAR m_szphone[14];<BR>ULONG lphoneStatus;<BR>};</TD></TR></TBODY></TABLE><BR>　　其中将要绑定的字段与变量名用BEGIN_ADO_BINDING宏关联起来。每个字段对应于两个变量，一个存放字段的值，另一个存放字段的状态。字段用从1开始的序号表示，如1，2，3等等。<BR><BR>　　特别要注意的是：如果要绑定的字段是字符串类型，则对应的字符数组的元素个数一定要比字段长度大2（比如m_szau_fname[22]，其绑定的字段au_fname的长度实际是20），不这样绑定就会失败。我分析多出的2可能是为了存放字符串结尾的空字符null和BSTR字符串开头的一个字（表示BSTR的长度）。这个问题对于初学者来说可能是一个意想不到的问题。<BR><BR>　　CADORecordBinding类的定义在icrsint.h文件里，内容是：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>class CADORecordBinding<BR>{<BR>public:<BR>STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) PURE;<BR>};<BR><BR>BEGIN_ADO_BINDING宏的定义也在icrsint.h文件里，内容是：<BR>#define BEGIN_ADO_BINDING(cls) public: \<BR>typedef cls ADORowClass; \<BR>const ADO_BINDING_ENTRY* STDMETHODCALLTYPE GetADOBindingEntries() { \<BR>static const ADO_BINDING_ENTRY rgADOBindingEntries[] = { <BR><BR>ADO_VARIABLE_LENGTH_ENTRY2宏的定义也在icrsint.h文件里：<BR>#define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)\<BR>{Ordinal, \<BR>DataType, \<BR>0, \<BR>0, \<BR>Size, \<BR>offsetof(ADORowClass, Buffer), \<BR>offsetof(ADORowClass, Status), \<BR>0, \<BR>classoffset(CADORecordBinding, ADORowClass), \<BR>Modify},<BR><BR>#define END_ADO_BINDING宏的定义也在icrsint.h文件里：<BR>#define END_ADO_BINDING() {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\<BR>return rgADOBindingEntries;}</TD></TR></TBODY></TABLE><BR>　　　(2). 绑定<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_RecordsetPtr Rs1;<BR>IADORecordBinding *picRs=NULL;<BR>CCustomRs rs;<BR>......<BR>Rs1-&gt;QueryInterface(__uuidof(IADORecordBinding), <BR>(LPVOID*)&amp;picRs));<BR>picRs-&gt;BindToRecordset(&amp;rs);</TD></TR></TBODY></TABLE><BR>　　派生出的类必须通过IADORecordBinding接口才能绑定，调用它的BindToRecordset方法就行了。<BR><BR>　　(3). rs中的变量即是当前记录字段的值<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>//Set sort and filter condition:<BR>// Step 4: Manipulate the data<BR>Rs1-&gt;Fields-&gt;GetItem("au_lname")-&gt;Properties-&gt;GetItem("Optimize")-&gt;Value = true; <BR>Rs1-&gt;Sort = "au_lname ASC";<BR>Rs1-&gt;Filter = "phone LIKE '415 5*'";<BR><BR>Rs1-&gt;MoveFirst();<BR>while (VARIANT_FALSE == Rs1-&gt;EndOfFile)<BR>{<BR>printf("Name: %s\t %s\tPhone: %s\n", <BR>(rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : ""), <BR>(rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : ""),<BR>(rs.lphoneStatus == adFldOK ? rs.m_szphone : ""));<BR>if (rs.lphoneStatus == adFldOK)<BR>strcpy(rs.m_szphone, "777");<BR>TESTHR(picRs-&gt;Update(&amp;rs)); // Add change to the batch<BR>Rs1-&gt;MoveNext();<BR>}<BR>Rs1-&gt;Filter = (long) adFilterNone;<BR>......<BR>if (picRs) picRs-&gt;Release();<BR>Rs1-&gt;Close();<BR>pConn-&gt;Close();</TD></TR></TBODY></TABLE><BR>　　只要字段的状态是adFldOK，就可以访问。如果修改了字段，不要忘了先调用picRs的Update（注意不是Recordset的Update），然后才关闭，也不要忘了释放picRs（即picRs-&gt;Release();）。<BR><BR>　　(4). 此时还可以用IADORecordBinding接口添加新纪录<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>if(FAILED(picRs-&gt;AddNew(&amp;rs)))<BR>......</TD></TR></TBODY></TABLE><BR>　　11. 访问长数据<BR><BR>　　在Microsoft SQL中的长数据包括text、image等这样长类型的数据，作为二进制字节来对待。<BR><BR>　　可以用Field对象的GetChunk和AppendChunk方法来访问。每次可以读出或写入全部数据的一部分，它会记住上次访问的位置。但是如果中间访问了别的字段后，就又得从头来了。<BR><BR>　　请看下面的例子：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>//写入一张照片到数据库：<BR>VARIANT varChunk;<BR>SAFEARRAY *psa;<BR>SAFEARRAYBOUND rgsabound[1];<BR><BR>//VT_ARRAY │ VT_UI1<BR>CFile f("h:\\aaa.jpg",Cfile::modeRead);<BR>BYTE bVal[ChunkSize+1];<BR>UINT uIsRead=0;<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)break;<BR>rgsabound[0].cElements =uIsRead;<BR>rgsabound[0].lLbound = 0;<BR>psa = SafeArrayCreate(VT_UI1,1,rgsabound);<BR>for(long index=0;index&lt;uIsRead;index++) <BR>{<BR>if(FAILED(SafeArrayPutElement(psa,&amp;index,&amp;bVal[index])))<BR>::MessageBox(NULL,"啊，又出毛病了。","提示",MB_OK │ MB_ICONWARNING);<BR>}<BR>varChunk.vt = VT_ARRAY│VT_UI1;<BR>varChunk.parray = psa;<BR>try{<BR>m_pRecordset-&gt;Fields-&gt;GetItem("photo")-&gt;AppendChunk(varChunk); <BR>}<BR>catch (_com_error &amp;e)<BR>{<BR>CString str=(char*)e.Description();<BR>::MessageBox(NULL,str+"\n又出毛病了。","提示",MB_OK │ MB_ICONWARNING);<BR>}<BR>::VariantClear(&amp;varChunk);<BR>::SafeArrayDestroyData( psa);<BR>if(uIsRead&lt;ChunkSize)break;<BR>}//while(1) <BR>f.Close();<BR><BR>//从数据库读一张照片：<BR>CFile f;<BR>f.Open("h:\\bbb.jpg",Cfile::modeWrite│Cfile::modeCreate);<BR>long lPhotoSize = m_pRecordset-&gt;Fields-&gt;Item["photo"]-&gt;ActualSize; <BR>long lIsRead=0;<BR><BR>_variant_t varChunk;<BR>BYTE buf[ChunkSize];<BR>while(lPhotoSize&gt;0)<BR>{<BR>lIsRead=lPhotoSize&gt;=ChunkSize? ChunkSize:lPhotoSize;<BR>varChunk = m_pRecordset-&gt;Fields-&gt;<BR>Item["photo"]-&gt;GetChunk(lIsRead);<BR>for(long index=0;index&lt;lIsRead;index++) <BR>{ <BR>::SafeArrayGetElement(varChunk.parray,&amp;index,buf+index); <BR>}<BR>f.Write(buf,lIsRead);<BR>lPhotoSize-=lIsRead;<BR>}//while()<BR>f.Close();</TD></TR></TBODY></TABLE><BR><BR><SPAN class=f14><FONT size=3>　　12. 使用SafeArray问题<BR><BR>　　学会使用SafeArray也是很重要的，因为在ADO编程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在网络环境中，数组是不能直接传递的，而必须将其包装成SafeArray。实质上SafeArray就是将通常的数组增加一个描述符，说明其维数、长度、边界、元素类型等信息。SafeArray也并不单独使用，而是将其再包装到VARIANT类型的变量中，然后才作为参数传送出去。在VARIANT的vt成员的值如果包含VT_ARRAY│...,那么它所封装的就是一个SafeArray，它的parray成员即是指向SafeArray的指针。SafeArray中元素的类型可以是VARIANT能封装的任何类型，包括VARIANT类型本身。 <BR><BR>　　使用SafeArray的具体步骤：<BR><BR>　　方法一：<BR><BR>　　包装一个SafeArray：<BR><BR>　　(1). 定义变量，如：<BR><BR></FONT>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>VARIANT varChunk;<BR>SAFEARRAY *psa;<BR>SAFEARRAYBOUND rgsabound[1];</TD></TR></TBODY></TABLE><BR>　　(2). 创建SafeArray描述符：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>uIsRead=f.Read(bVal,ChunkSize);//read array from a file.<BR>if(uIsRead==0)break;<BR>rgsabound[0].cElements =uIsRead;<BR>rgsabound[0].lLbound = 0;<BR>psa = SafeArrayCreate(VT_UI1,1,rgsabound);</TD></TR></TBODY></TABLE><BR>　　(3). 放置数据元素到SafeArray：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>for(long index=0;index&lt;uIsRead;index++) <BR>{<BR>if(FAILED(SafeArrayPutElement(psa,&amp;index,&amp;bVal[index])))<BR>::MessageBox(NULL,"出毛病了。","提示",MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　一个一个地放，挺麻烦的。<BR><BR>　　(4). 封装到VARIANT内：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>varChunk.vt = VT_ARRAY│VT_UI1;<BR>varChunk.parray = psa;</TD></TR></TBODY></TABLE><BR>　　这样就可以将varChunk作为参数传送出去了。<BR><BR>　　读取SafeArray中的数据的步骤：<BR><BR>　　(1). 用SafeArrayGetElement一个一个地读<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>BYTE buf[lIsRead];<BR>for(long index=0;index&lt;lIsRead;index++) <BR>{ <BR>::SafeArrayGetElement(varChunk.parray,&amp;index,buf+index); <BR>}</TD></TR></TBODY></TABLE><BR>　　就读到缓冲区buf里了。<BR><BR>　　方法二：<BR><BR>　　使用SafeArrayAccessData直接读写SafeArray的缓冲区：<BR><BR>　　(1). 读缓冲区：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>BYTE *buf;<BR>SafeArrayAccessData(varChunk.parray, (void **)&amp;buf);<BR>f.Write(buf,lIsRead);<BR>SafeArrayUnaccessData(varChunk.parray);</TD></TR></TBODY></TABLE><BR>　　(2). 写缓冲区：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>BYTE *buf;<BR>::SafeArrayAccessData(psa, (void **)&amp;buf);<BR>for(long index=0;index&lt;uIsRead;index++) <BR>{<BR>buf[index]=bVal[index]; <BR>}<BR>::SafeArrayUnaccessData(psa);<BR><BR>varChunk.vt = VT_ARRAY│VT_UI1;<BR>varChunk.parray = psa;</TD></TR></TBODY></TABLE><BR>　　这种方法读写SafeArray都可以，它直接操纵SafeArray的数据缓冲区，比用SafeArrayGetElement和SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData(psa)，否则会出错的。<BR><BR>　　13. 使用书签( bookmark )<BR><BR>　　书签可以唯一标识记录集中的一个记录，用于快速地将当前记录移回到已访问过的记录，以及进行过滤等等。Provider会自动为记录集中的每一条记录产生一个书签，我们只需要使用它就行了。我们不能试图显示、修改或比较书签。ADO用记录集的Bookmark属性表示当前记录的书签。<BR><BR>　　用法步骤：<BR><BR>　　(1). 建立一个VARIANT类型的变量<BR><BR>_variant_t VarBookmark;<BR><BR>　　(2). 将当前记录的书签值存入该变量<BR><BR>　　也就是记录集的Bookmark属性的当前值。<BR><BR>VarBookmark = rst-&gt;Bookmark;<BR><BR>　　(3). 返回到先前的记录<BR><BR>　　将保存的书签值设置到记录集的书签属性中：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>// Check for whether bookmark set for a record<BR>if (VarBookmark.vt == VT_EMPTY)<BR>printf("No Bookmark set!\n");<BR>else <BR>rst-&gt;Bookmark = VarBookmark;</TD></TR></TBODY></TABLE><BR>　　设置完后，当前记录即会移动到该书签指向的记录。<BR><BR><BR><SPAN class=f14><FONT size=3>　　14、设置过滤条件<BR><BR>　　Recordset对象的Filter属性表示了当前的过滤条件。它的值可以是以AND或OR连接起来的条件表达式（不含WHERE关键字）、由书签组成的数组或ADO提供的FilterGroupEnum枚举值。为Filter属性设置新值后Recordset的当前记录指针会自动移动到满足过滤条件的第一个记录。例如：<BR><BR></FONT>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>rst-&gt;Filter = _bstr_t ("姓名='赵薇' AND 性别=’女’");</TD></TR></TBODY></TABLE><BR>　　在使用条件表达式时应注意下列问题：<BR><BR>　　（1）、可以用圆括号组成复杂的表达式<BR><BR>　　例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>rst-&gt;Filter = _bstr_t ("(姓名='赵薇' AND 性别=’女’) OR AGE&lt;25");</TD></TR></TBODY></TABLE><BR>　　但是微软不允许在括号内用OR，然后在括号外用AND，例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>rst-&gt;Filter = _bstr_t ("(姓名='赵薇' OR 性别=’女’) AND AGE&lt;25");</TD></TR></TBODY></TABLE><BR>　　必须修改为：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>rst-&gt;Filter = _bstr_t ("(姓名='赵薇' AND AGE&lt;25) OR (性别=’女’ AND AGE&lt;25)");</TD></TR></TBODY></TABLE><BR>　　（2）、表达式中的比较运算符可以是LIKE<BR><BR>　　LIKE后被比较的是一个含有通配符*的字符串，星号表示若干个任意的字符。<BR><BR>　　字符串的首部和尾部可以同时带星号*<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>rst-&gt;Filter = _bstr_t ("姓名 LIKE '*赵*' ");</TD></TR></TBODY></TABLE><BR>　　也可以只是尾部带星号：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>rst-&gt;Filter = _bstr_t ("姓名 LIKE '赵*' ");</TD></TR></TBODY></TABLE><BR>　　Filter属性值的类型是Variant，如果过滤条件是由书签组成的数组，则需将该数组转换为SafeArray，然后再封装到一个VARIANT或_variant_t型的变量中，再赋给Filter属性。<BR><BR>　　15、索引与排序<BR><BR>　　（1）、建立索引<BR><BR>　　当以某个字段为关键字用Find方法查找时，为了加快速度可以以该字段为关键字在记录集内部临时建立索引。只要将该字段的Optimize属性设置为true即可，例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>pRst-&gt;Fields-&gt;GetItem("姓名")-&gt;Properties-&gt;<BR>GetItem("Optimize")-&gt;PutValue("True");<BR>pRst-&gt;Find("姓名 = '赵薇'",1,adSearchForward);<BR>......<BR>pRst-&gt;Fields-&gt;GetItem("姓名")-&gt;Properties-&gt;<BR>GetItem("Optimize")-&gt;PutValue("False");<BR>pRst-&gt;Close();</TD></TR></TBODY></TABLE><BR>　　说明：Optimize属性是由Provider提供的属性（在ADO中称为动态属性），ADO本身没有此属性。<BR><BR>　　（2）、排序<BR><BR>　　要排序也很简单，只要把要排序的关键字列表设置到Recordset对象的Sort属性里即可，例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>pRstAuthors-&gt;CursorLocation = adUseClient;<BR>pRstAuthors-&gt;Open("SELECT * FROM mytable",<BR>_variant_t((IDispatch *) pConnection),<BR>adOpenStatic, adLockReadOnly, adCmdText);<BR>......<BR>pRst-&gt;Sort = "姓名 DESC, 年龄 ASC";</TD></TR></TBODY></TABLE><BR>　　关键字（即字段名）之间用逗号隔开，如果要以某关键字降序排序，则应在该关键字后加一空格，再加DESC（如上例）。升序时ASC加不加无所谓。本操作是利用索引进行的，并未进行物理排序，所以效率较高。<BR>但要注意，在打开记录集之前必须将记录集的CursorLocation属性设置为adUseClient，如上例所示。Sort属性值在需要时随时可以修改。<BR><BR>　　16、事务处理<BR><BR>　　ADO中的事务处理也很简单，只需分别在适当的位置调用Connection对象的三个方法即可，这三个方法是：<BR><BR>　　（1）、在事务开始时调用<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>pCnn-&gt;BeginTrans();</TD></TR></TBODY></TABLE><BR>　　（2）、在事务结束并成功时调用<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>pCnn-&gt;CommitTrans ();</TD></TR></TBODY></TABLE><BR>　　（3）、在事务结束并失败时调用<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>pCnn-&gt;RollbackTrans ();</TD></TR></TBODY></TABLE><BR>　　在使用事务处理时，应尽量减小事务的范围，即减小从事务开始到结束（提交或回滚）之间的时间间隔，以便提高系统效率。需要时也可在调用BeginTrans()方法之前，先设置Connection对象的IsolationLevel属性值，详细内容参见MSDN中有关ADO的技术资料。<BR><BR><SPAN class=f14><FONT size=3>　　<B>三、使用ADO编程常见问题解答</B><BR><BR>　　以下均是针对MS SQL 7.0编程时所遇问题进行讨论。<BR><BR>　　1、连接失败可能原因<BR><BR>　　Enterprise Managemer内，打开将服务器的属性对话框，在Security选项卡中，有一个选项Authentication。<BR><BR>　　如果该选项是Windows NT only，则你的程序所用的连接字符串就一定要包含Trusted_Connection参数，并且其值必须为yes，如：<BR><BR></FONT>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>"Provider=SQLOLEDB;Server=888;Trusted_Connection=yes"<BR>";Database=master;uid=lad;";</TD></TR></TBODY></TABLE><BR>　　如果不按上述操作，程序运行时连接必然失败。<BR><BR>　　如果Authentication选项是SQL Server and Windows NT，则你的程序所用的连接字符串可以不包含Trusted_Connection参数，如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>"Provider=SQLOLEDB;Server=888;Database=master;uid=lad;pwd=111;";</TD></TR></TBODY></TABLE><BR>　　因为ADO给该参数取的默认值就是no，所以可以省略。我认为还是取默认值比较安全一些。<BR><BR>　　2、改变当前数据库的方法<BR><BR>　　使用Tansct-SQL中的USE语句即可。<BR><BR>　　3、如何判断一个数据库是否存在<BR><BR>　　(1)、可打开master数据库中一个叫做SCHEMATA的视图，其内容列出了该服务器上所有的数据库名称。<BR><BR>　　(2) 、更简便的方法是使用USE语句，成功了就存在；不成功，就不存在。例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>try{<BR>m_pConnect-&gt;Execute ( _bstr_t("USE INSURANCE_2002"),NULL,<BR>adCmdText│adExecuteNoRecords );<BR>}<BR>catch (_com_error &amp;e)<BR>{<BR>blSuccess=FALSE;<BR>CString str="数据库INSURANCE_2002不存在！\n";<BR>str+=e.Description();<BR>::MessageBox(NULL,str,"警告",MB_OK │ MB_ICONWARNING); <BR>}</TD></TR></TBODY></TABLE><BR>　　4、判断一个表是否存在<BR><BR>　　（1）、同样判断一个表是否存在，也可以用是否成功地打开它来判断，十分方便，例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>try{<BR>m_pRecordset-&gt;Open(_variant_t("mytable"),<BR>_variant_t((IDispatch *)m_pConnection,true), adOpenKeyset,<BR>adLockOptimistic, adCmdTable);<BR>}<BR>catch (_com_error &amp;e)<BR>{<BR>::MessageBox(NULL,"该表不存在。","提示",MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　(2)、要不然可以采用麻烦一点的办法，就是在MS-SQL服务器上的每个数据库中都有一个名为sysobjects的表，查看此表的内容即知指定的表是否在该数据库中。<BR><BR>　　(3)、同样，每个数据库中都有一个名为TABLES的视图(View)，查看此视图的内容即知指定的表是否在该数据库中。<BR><BR>　　5、类型转换问题<BR><BR>　　（1）、类型VARIANT_BOOL<BR><BR>　　类型VARIANT_BOOL等价于short类型。The VARIANT_BOOL is equivalent to short. see it's definition below: <BR>typdef short VARIANT_BOOL<BR><BR>　　（2）、_com_ptr_t类的类型转换<BR><BR>　　_ConnectionPtr可以自动转换成IDspatch*类型，这是因为_ConnectionPtr实际上是_com_ptr_t类的一个实例，而这个类有此类型转换函数。<BR><BR>　　同理，_RecordsetPtr和_CommandPtr也都可以这样转换。<BR><BR>　　（3）、_bstr_t和_variant_t类<BR><BR>　　在ADO编程时，_bstr_t和_variant_t这两个类很有用，省去了许多BSTR和VARIANT类型转换的麻烦。<BR><BR>　　6、打开记录集时的问题<BR><BR>　　在打开记录集时，在调用Recordset的Open方法时，其最后一个参数里一定不能包含adAsyncExecute，否则将因为是异步操作，在读取数据时无法读到数据。<BR><BR>　　7、异常处理问题<BR><BR>　　对所有调用ADO的语句一定要用try和catch语句捕捉异常，否则在发生异常时，程序会异常退出。<BR><BR>　　8、使用SafeArray问题<BR><BR>　　在初学使用中，我曾遇到一个伤脑筋的问题，一定要注意：<BR><BR>　　在定义了SAFEARRAY的指针后，如果打算重复使用多次，则在中间可以调用::SafeArrayDestroyData释放数据，但决不能调用::SafeArrayDestroyDescriptor，否则必然出错，即使调用SafeArrayCreate也不行。例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>SAFEARRAY *psa;<BR>......<BR>//When the data are no longer to be used:<BR>::SafeArrayDestroyData( psa);</TD></TR></TBODY></TABLE><BR>　　我分析在定义psa指针时，一个SAFEARRAY的实例（也就是SAFEARRAY描述符）也同时被自动建立了。但是只要一调用::SafeArrayDestroyDescriptor，描述符就被销毁了。<BR><BR>　　所以我认为::SafeArrayDestroyDescriptor可以根本就不调用，即使调用也必须在最后调用。<BR><BR>　　9、重复使用命令对象问题<BR><BR>　　一个命令对象如果要重复使用多次（尤其是带参数的命令），则在第一次执行之前，应将它的Prepared属性设置为TRUE。这样会使第一次执行减慢，但却可以使以后的执行全部加快。<BR><BR>　　10、绑定字符串型字段问题<BR><BR>　　如果要绑定的字段是字符串类型，则对应的字符数组的元素个数一定要比字段长度大2（比如m_szau_fname[22]，其绑定的字段au_fname的长度实际是20），不这样绑定就会失败。<BR><BR>　　11、使用AppendChunk的问题<BR><BR>　　当用AddNew方法刚刚向记录集内添加一个新记录之后，不能首先向一个长数据字段（image类型）写入数据，必须先向其他字段写入过数据之后，才能调用AppendChunk写该字段，否则出错。也就是说，AppendChunk不能紧接在AddNew之后。另外，写入其他字段后还必须紧接着调用AppendChunk，而不能调用记录集的Update方法后，才调用AppendChunk，否则调用AppendChunk时也会出错。换句话说，就是必须AppendChunk在前，Update在后。因而这个时候就不能使用带参数的AddNew了，因为带参数的AddNew会自动调用记录集的Update，所以AppendChunk就跑到Update的后面了，就只有出错了！因此，这时应该用不带参数的AddNew。<BR><BR>　　我推测这可能是MS SQL 7.0的问题，在MS SQL 2000中则不存在这些问题，但是AppendChunk仍然不能在Update之后。<BR><BR>　　<B>四、小结</B><BR><BR>　　一般情况下，Connection和Command的Execute用于执行不产生记录集的命令，而Recordset的Open用于产生一个记录集，当然也不是绝对的。特别Command主要是用于执行参数化的命令，可以直接由Command对象执行，也可以将Command对象传递给Recordset的Open。</SPAN></SPAN></SPAN></DIV><BR></SPAN><img src ="http://www.cppblog.com/ivenher/aggbug/2294.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-12-30 18:32 <a href="http://www.cppblog.com/ivenher/articles/2294.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual C++ ADO数据库编程入门（上）</title><link>http://www.cppblog.com/ivenher/articles/2293.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Fri, 30 Dec 2005 10:31:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2293.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2293.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2293.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2293.html</trackback:ping><description><![CDATA[<DIV class=postText>　　ADO 是目前在Windows环境中比较流行的客户端数据库编程技术。ADO是建立在OLE DB底层技术之上的高级编程接口，因而它兼具有强大的数据处理功能（处理各种不同类型的数据源、分布式的数据处理等等）和极其简单、易用的编程接口，因而得到了广泛的应用。而且按微软公司的意图，OLE DB和ADO将逐步取代 ODBC和DAO。现在介绍ADO各种应用的文章和书籍有很多，本文着重站在初学者的角度，简要探讨一下在VC++中使用ADO编程时的一些问题。我们希望阅读本文之前，您对ADO技术的基本原理有一些了解。<BR><BR>　　<B>一、在VC++中使用ADO编程</B><BR><BR>　　ADO实际上就是由一组Automation对象构成的组件，因此可以象使用其它任何Automation对象一样使用ADO。ADO中最重要的对象有三个：Connection、Command和Recordset，它们分别表示连接对象、命令对象和记录集对象。如果您熟悉使用MFC中的ODBC类（CDatabase、CRecordset)编程，那么学习ADO编程就十分容易了。<BR><BR>　　使用ADO编程时可以采用以下三种方法之一：<BR><BR>　　1、使用预处理指令#import<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#c0c0c0 border=1>
<TBODY>
<TR>
<TD>#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \<BR>no_namespace rename("EOF", "EndOfFile")</TD></TR></TBODY></TABLE><BR>　　但要注意不能放在stdAfx.h文件的开头，而应该放在所有include指令的后面。否则在编译时会出错。<BR>程序在编译过程中，VC++会读出msado15.dll中的类型库信息，自动产生两个该类型库的头文件和实现文件msado15.tlh和msado15.tli（在您的Debug或Release目录下）。在这两个文件里定义了ADO的所有对象和方法，以及一些枚举型的常量等。我们的程序只要直接调用这些方法就行了，与使用MFC中的COleDispatchDriver类调用Automation对象十分类似。<BR><BR>　　2、使用MFC中的CIDispatchDriver<BR><BR>　　就是通过读取msado15.dll中的类型库信息，建立一个COleDispatchDriver类的派生类，然后通过它调用ADO对象。<BR><BR>　　3、直接用COM提供的API<BR><BR>　　如使用如下代码：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>CLSID clsid;<BR>HRESULT hr = ::CLSIDFromProgID(L"ADODB.Connection", &amp;clsid);<BR>if(FAILED(hr))<BR>{...}<BR>::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IDispatch, (void **)<BR>&amp;pDispatch);<BR>if(FAILED(hr))<BR>{...}</TD></TR></TBODY></TABLE><BR>　　以上三种方法，第一和第二种类似，可能第一种好用一些，第三种编程可能最麻烦。但可能第三种方法也是效率最高的，程序的尺寸也最小，并且对ADO的控制能力也最强。<BR><BR>　　据微软资料介绍，第一种方法不支持方法调用中的默认参数，当然第二种方法也是这样，但第三种就不是这样了。采用第三种方法的水平也最高。当你需要绕过ADO而直接调用OLE DB底层的方法时，就一定要使用第三种方法了。<BR><BR>　　ADO编程的关键，就是熟练地运用ADO提供的各种对象(object)、方法(method)、属性(property)和容器（collection）。另外，如果是在MS SQL或Oracle等大型数据库上编程，还要能熟练使用SQL语言。<BR><BR><BR><SPAN class=f14><FONT size=3>　　<B>二、使用#import方法的编程步骤</B><BR><BR>　　这里建议您使用#import的方法，因为它易学、易用，代码也比较简洁。<BR><BR>　　1、 添加#import指令<BR><BR>　　打开stdafx.h文件，将下列内容添加到所有的include指令之后：<BR><BR></FONT>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>#include &lt;icrsint.h&gt; //Include support for VC++ Extensions<BR>#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \<BR>no_namespace rename("EOF", "adoEOF")</TD></TR></TBODY></TABLE><BR>　　其中icrsint.h文件包含了VC++扩展的一些预处理指令、宏等的定义，用于COM编程时使用。<BR><BR>　　2、定义_ConnectionPtr型变量，并建立数据库连接<BR><BR>　　建立了与数据库服务器的连接后，才能进行其他有关数据库的访问和操作。ADO使用Connection对象来建立与数据库服务器的连接，所以它相当于MFC中的CDatabase类。和CDatabase类一样，调用Connection对象的Open方法即可建立与服务器的连接。<BR><BR>　　数据类型 _ConnectionPtr实际上就是由类模板_com_ptr_t而得到的一个具体的实例类，其定义可以到msado15.tlh、comdef.h 和comip.h这三个文件中找到。在msado15.tlh中有：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_COM_SMARTPTR_TYPEDEF(_Collection, __uuidof(_Collection));</TD></TR></TBODY></TABLE><BR>　　经宏扩展后就得到了_ConnectionPtr类。_ConnectionPtr类封装了Connection对象的Idispatch接口指针，及一些必要的操作。我们就是通过这个指针来操纵Connection对象。类似地，后面用到的_CommandPtr和_RecordsetPtr类型也是这样得到的，它们分别表示命令对象指针和记录集对象的指针。<BR><BR>　　（1）、连接到MS SQL Server<BR><BR>　　注意连接字符串的格式，提供正确的连接字符串是成功连接到数据库服务器的第一步，有关连接字符串的详细信息参见微软MSDN Library光盘。<BR><BR>　　本例连接字符串中的server_name，database_name，user_name和password在编程时都应该替换成实际的内容。<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_ConnectionPtr pMyConnect=NULL;<BR>HRESULT hr=pMyConnect.CreateInstance(__uuidof(Connection)));<BR>if(FAILED(hr))return;<BR><BR>_bstr_t strConnect="Provider=SQLOLEDB; Server=server_name;"<BR>"Database=database_name; uid=user_name; pwd=password;"; <BR>//connecting to the database server now:<BR>try{pMyConnect-&gt;Open(strConnect,"","",NULL);}<BR>catch (_com_error &amp;e)<BR>{<BR>::MessageBox(NULL,e.Description(),"警告",MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　注意Connection对象的Open方法中的连接字符串参数必须是BSTR或_bstr_t类型。另外，本例是直接通过OLE DB Provider建立连接，所以无需建立数据源。<BR><BR>　　（2）、通过ODBC Driver连接到Database Server连接字符串格式与直接用ODBC编程时的差不多：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_bstr_t strConnect="DSN=datasource_name; Database=database_name; uid=user_name; pwd=password;";</TD></TR></TBODY></TABLE><BR>　　此时与ODBC编程一样，必须先建立数据源。<BR><BR>　　3、定义_RecordsetPtr型变量，并打开数据集<BR><BR>　　定义_RecordsetPtr型变量，然后通过它调用Recordset对象的Open方法，即可打开一个数据集。所以Recordset对象与MFC中的CRecordset类类似，它也有当前记录、当前记录指针的概念。如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_RecordsetPtr m_pRecordset;<BR>if(!FAILED(m_pRecordset.CreateInstance( __uuidof( Recordset )))<BR>{<BR>m_pDoc-&gt;m_initialized=FALSE;<BR>return;<BR>}<BR><BR>try{<BR>m_pRecordset-&gt;Open(_variant_t("mytable"),<BR>_variant_t((IDispatch *)pMyConnect,true), adOpenKeyset,<BR>adLockOptimistic, adCmdTable);<BR>}<BR>catch (_com_error &amp;e)<BR>{<BR>::MessageBox(NULL,"无法打开mytable表。","提示",<BR>MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　Recordset对象的Open方法非常重要，它的第一个参数可以是一个SQL语句、一个表的名字或一个命令对象等等；第二个参数就是前面建立的连接对象的指针。此外，用Connection和Command对象的Execute方法也能得到记录集，但是只读的。<BR><BR><BR><SPAN class=f14><FONT size=3>　　4、读取当前记录的数据<BR><BR>　　我认为读取数据的最方便的方法如下：<BR><BR></FONT>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>try{<BR>m_pRecordset-&gt;MoveFirst(); <BR>while(m_pRecordset-&gt;adoEOF==VARIANT_FALSE) <BR>{<BR>//Retrieve column's value: <BR>CString sName=(char*)(_bstr_t)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("name"))-&gt;Value);<BR>short cAge=(short)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("age"))-&gt;Value);<BR>//Do something what you want to do:<BR>......<BR>m_pRecordset-&gt;MoveNext(); <BR>}<BR>}//try<BR>catch (_com_error &amp;e)<BR>{<BR>CString str=(char*)e.Description();<BR>::MessageBox(NULL,str+"\n又出毛病了。","提示",<BR>MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　本例中的name和age都是字段名，读取的字段值分别保存在sName和cAge变量内。例中的Fields是Recordset对象的容器，GetItem方法返回的是Field对象，而Value则是Field对象的一个属性（即该字段的值）。通过此例，应掌握操纵对象属性的方法。例如，要获得Field 对象的Value属性的值可以直接用属性名Value来引用它（如上例），但也可以调用Get方法，例如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>CString sName=(char*)(_bstr_t)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("name"))-&gt;GetValue());</TD></TR></TBODY></TABLE><BR>　　从此例还可以看到，判断是否到达记录集的末尾，使用记录集的adoEOF属性，其值若为真即到了结尾，反之则未到。判断是否到达记录集开头，则可用BOF属性。<BR><BR>　　另外，读取数据还有一个方法，就是定义一个绑定的类，然后通过绑定的变量得到字段值（详见后面的介绍）。<BR><BR>　　5、修改数据<BR><BR>　　方法一：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>try{<BR>m_pRecordset-&gt;MoveFirst(); <BR>while(m_pRecordset-&gt;adoEOF==VARIANT_FALSE) <BR>{ <BR>m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("姓名"))-&gt;Value=_bstr_t("赵薇");<BR>......<BR>m_pRecordset-&gt;Update();<BR><BR>m_pRecordset-&gt;MoveNext(); <BR>}<BR>}//try</TD></TR></TBODY></TABLE><BR>　　改变了Value属性的值，即改变了字段的值。<BR><BR>　　方法二：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("姓名"))-&gt;PutValue(_bstr_t("赵薇"));</TD></TR></TBODY></TABLE><BR>　　方法三：就是用定义绑定类的方法（详见后面的介绍）。<BR><BR>　　6、添加记录<BR><BR>　　新记录添加成功后，即自动成为当前记录。AddNew方法有两种形式，一个含有参数，而另一个则不带参数。<BR><BR>　　方法一（不带参数）：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>// Add new record into this table:<BR>try{<BR>if(!m_pRecordset-&gt;Supports(adAddNew)) return;<BR><BR>m_pRecordset-&gt;AddNew(); <BR>m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("姓名"))-&gt;Value=_bstr_t("赵薇");<BR>m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("性别"))-&gt;Value=_bstr_t("女");<BR>m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("age"))-&gt;Value=_variant_t((short)20);<BR>m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("marry"))-&gt;Value=_bstr_t("未婚");<BR>m_pRecordset-&gt;Update(); <BR>}//try<BR>catch (_com_error &amp;e)<BR>{<BR>::MessageBox(NULL, "又出毛病了。","提示",MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　这种方法弄完了还要调用Update()。<BR><BR>　　方法二（带参数）：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_variant_t varName[4],narValue[4];<BR>varName[0] = L"姓名";<BR>varName[1] = L"性别";<BR>varName[2] = L"age";<BR>varName[3] = L"marry";<BR>narValue[0]=_bstr_t("赵薇");<BR>narValue[1]=_bstr_t("女");<BR>narValue[2]=_variant_t((short)20);<BR>narValue[3]=_bstr_t("未婚");<BR><BR>const int nCrit = sizeof varName / sizeof varName[0];<BR>// Create SafeArray Bounds and initialize the array<BR>SAFEARRAYBOUND rgsaName[1],rgsaValue[1];<BR>rgsaName[0].lLbound = 0; <BR>rgsaName[0].cElements = nCrit;<BR>SAFEARRAY *psaName = SafeArrayCreate( VT_VARIANT, 1, rgsaName );<BR>rgsaValue[0].lLbound = 0;<BR>rgsaValue[0].cElements = nCrit;<BR>SAFEARRAY *psaValue = SafeArrayCreate( VT_VARIANT, 1, rgsaValue );<BR>// Set the values for each element of the array<BR>HRESULT hr1=S_OK.hr2=S_OK;<BR>for( long i = 0 ; i &lt; nCrit &amp;&amp; SUCCEEDED( hr1 ) &amp;&amp; SUCCEEDED( hr2 );i++) <BR>{ <BR>hr1=SafeArrayPutElement(psaName, &amp;i,&amp;varName[i]);<BR>hr2=SafeArrayPutElement(psaValue, &amp;i,&amp;narValue[i]); }<BR><BR>// Initialize and fill the SafeArray<BR>VARIANT vsaName,vsaValue; <BR>vsaName.vt = VT_VARIANT │ VT_ARRAY;<BR>vsaValue.vt = VT_VARIANT │ VT_ARRAY;<BR>V_ARRAY(&amp;vsaName) = psaName;//&amp;vsaName-&gt;parray=psaName;<BR>//see definition in oleauto.h file.<BR>V_ARRAY(&amp;vsaValue) = psaValue;<BR><BR>// Add a new record:<BR>m_pRecordset-&gt;AddNew(vsaName,vsaValue);</TD></TR></TBODY></TABLE><BR>　　这种方法不需要调用Update，因为添加后，ADO会自动调用它。此方法主要是使用SafeArray挺麻烦。<BR><BR>　　方法三：就是用定义绑定类的方法（详见后面的介绍）。<BR><BR><FONT size=3>　7、删除记录<BR><BR>　　调用Recordset的Delete方法就行了，删除的是当前记录。要了解Delete的其它用法请查阅参考文献。<BR><BR></FONT>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>try{<BR>m_pRecordset-&gt;MoveFirst(); <BR>while(m_pRecordset-&gt;adoEOF==VARIANT_FALSE) <BR>{<BR>CString sName=(char*)(_bstr_t)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>(_variant_t("姓名"))-&gt;Value);<BR>if(::MessageBox(NULL,"姓名="+sName+"\n删除她吗？",<BR>"提示",MB_YESNO │ MB_ICONWARNING)==IDYES)<BR>{<BR>m_pRecordset-&gt;Delete(adAffectCurrent); <BR>m_pRecordset-&gt;Update();<BR>}<BR>m_pRecordset-&gt;MoveNext(); <BR>}<BR>}//try<BR>catch (_com_error &amp;e)<BR>{<BR>::MessageBox(NULL,"又出毛病了。","提示",MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　8、使用带参数的命令<BR><BR>　　Command对象所代表的就是一个Provider能够理解的命令，如SQL语句等。使用Command对象的关键就是把表示命令的语句设置到CommandText属性中，然后调用Command对象的Execute方法就行了。一般情况下在命令中无需使用参数，但有时使用参数，可以增加其灵活性和效率。<BR><BR>　　(1). 建立连接、命令对象和记录集对象<BR><BR>　　本例中表示命令的语句就是一个SQL语句（SELECT语句）。SELECT语句中的问号?就代表参数，如果要多个参数，就多放几个问号，每个问号代表一个参数。<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>_ConnectionPtr Conn1;<BR>_CommandPtr Cmd1;<BR>ParametersPtr *Params1 = NULL; // Not an instance of a smart pointer.<BR>_ParameterPtr Param1;<BR>_RecordsetPtr Rs1;<BR><BR>try<BR>{<BR>// Create Connection Object (1.5 Version)<BR>Conn1.CreateInstance( __uuidof( Connection ) );<BR>Conn1-&gt;ConnectionString = bstrConnect;<BR>Conn1-&gt;Open( bstrEmpty, bstrEmpty, bstrEmpty, -1 );<BR>// Create Command Object<BR>Cmd1.CreateInstance( __uuidof( Command ) );<BR>Cmd1-&gt;ActiveConnection = Conn1;<BR>Cmd1-&gt;CommandText = _bstr_t("SELECT * FROM mytable WHERE age&lt; ?");<BR>}//try</TD></TR></TBODY></TABLE><BR>　　要注意命令对象必须与连接对象关联起来才能起作用，本例中将命令对象的ActiveConnection属性设置为连接对象的指针，即为此目的：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>Cmd1-&gt;ActiveConnection = Conn1;</TD></TR></TBODY></TABLE><BR>　　(2). 创建参数对象，并给参数赋值<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>// Create Parameter Object<BR>Param1 = Cmd1-&gt;CreateParameter( _bstr_t(bstrEmpty),<BR>adInteger,<BR>adParamInput,<BR>-1,<BR>_variant_t( (long) 5) );<BR>Param1-&gt;Value = _variant_t( (long) 5 );<BR>Cmd1-&gt;Parameters-&gt;Append( Param1 );</TD></TR></TBODY></TABLE><BR>　　用命令对象的方法来创建一个参数对象，其中的长度参数（第三个）如果是固定长度的类型，就填-1，如果是字符串等可变长度的就填其实际长度。Parameters是命令对象的一个容器，它的Append方法就是把创建的参数对象追加到该容器里。Append进去的参数按先后顺序与SQL语句中的问号从左至右一一对应。<BR><BR>　　(3). 执行命令打开记录集<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>// Open Recordset Object<BR>Rs1 = Cmd1-&gt;Execute( &amp;vtEmpty, &amp;vtEmpty2, adCmdText );</TD></TR></TBODY></TABLE><BR>　　但要注意，用Command和Connection对象的Execute方法得到的Recordset是只读的。因为在打开Recordset之前，我们无法设置它的LockType属性（其默认值为只读）。而在打开之后设置LockType不起作用。<BR><BR>　　我发现用上述方法得到记录集Rs1后，不但Rs1中的记录无法修改，即使直接用SQL语句修改同一表中任何记录都不行。<BR><BR>　　要想能修改数据，还是要用Recordset自己的Open方法才行，如：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>try{<BR>m_pRecordset-&gt;Open((IDispatch *) Cmd1, vtMissing,<BR>adOpenStatic, adLockOptimistic, adCmdUnspecified);<BR>}<BR>catch (_com_error &amp;e)<BR>{<BR>::MessageBox(NULL,"mytable表不存在。","提示",MB_OK │ MB_ICONWARNING);<BR>}</TD></TR></TBODY></TABLE><BR>　　Recordset对象的Open方法真是太好了，其第一个参数可以是SQL语句、表名字、命令对象指针等等。<BR><BR>　　9、响应ADO的通知事件<BR><BR>　　通知事件就是当某个特定事件发生时，由Provider通知客户程序，换句话说，就是由Provider调用客户程序中的一个特定的方法（即事件的处理函数）。所以为了响应一个事件，最关键的就是要实现事件的处理函数。<BR><BR>　　(1). 从ConnectionEventsVt接口派生出一个类<BR><BR>　　为了响应_Connection的通知事件，应该从ConnectionEventsVt接口派生出一个类：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>class CConnEvent : public ConnectionEventsVt<BR>{<BR>private:<BR>ULONG m_cRef;<BR>public:<BR>CConnEvent() { m_cRef = 0; };<BR>~CConnEvent() {};<BR><BR>STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);<BR>STDMETHODIMP_(ULONG) AddRef(void);<BR>STDMETHODIMP_(ULONG) Release(void);<BR>STDMETHODIMP raw_InfoMessage( <BR>struct Error *pError,<BR>EventStatusEnum *adStatus,<BR>struct _Connection *pConnection);<BR>STDMETHODIMP raw_BeginTransComplete( <BR>LONG TransactionLevel,<BR>struct Error *pError,<BR>EventStatusEnum *adStatus,<BR>struct _Connection *pConnection);<BR>......<BR>}; </TD></TR></TBODY></TABLE><BR>　　　(2). 实现每一个事件的处理函数(凡是带raw_前缀的方法都把它实现了)：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>STDMETHODIMP CConnEvent::raw_InfoMessage( <BR>struct Error *pError,<BR>EventStatusEnum *adStatus,<BR>struct _Connection *pConnection)<BR>{<BR>*adStatus = adStatusUnwantedEvent;<BR>return S_OK;<BR>};</TD></TR></TBODY></TABLE><BR>　　有些方法虽然你并不需要，但也必须实现它，只需简单地返回一个S_OK即可。但如果要避免经常被调用，还应在其中将adStatus参数设置为adStatusUnwantedEvent，则在本次调用后，以后就不会被调用了。<BR>另外还必须实现QueryInterface, AddRef, 和Release三个方法: <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv) <BR>{<BR>*ppv = NULL;<BR>if (riid == __uuidof(IUnknown) ││ <BR>riid == __uuidof(ConnectionEventsVt)) *ppv = this;<BR>if (*ppv == NULL)<BR>return ResultFromScode(E_NOINTERFACE);<BR>AddRef();<BR>return NOERROR;<BR>}<BR>STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; };<BR>STDMETHODIMP_(ULONG) CConnEvent::Release()<BR>{ <BR>if (0 != --m_cRef) return m_cRef;<BR>delete this;<BR>return 0;<BR>}</TD></TR></TBODY></TABLE><BR>　　(3). 开始响应通知事件<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>// Start using the Connection events<BR>IConnectionPointContainer *pCPC = NULL;<BR>IConnectionPoint *pCP = NULL;<BR><BR>hr = pConn.CreateInstance(__uuidof(Connection));<BR>if (FAILED(hr)) return;<BR><BR>hr = pConn-&gt;QueryInterface(__uuidof(IConnectionPointContainer), <BR>(void **)&amp;pCPC);<BR>if (FAILED(hr)) return;<BR>hr = pCPC-&gt;FindConnectionPoint(__uuidof(ConnectionEvents), &amp;pCP);<BR>pCPC-&gt;Release();<BR>if (FAILED(hr)) return;<BR><BR>pConnEvent = new CConnEvent();<BR>hr = pConnEvent-&gt;QueryInterface(__uuidof(IUnknown), (void **) &amp;pUnk);<BR>if (FAILED(hr)) return rc; <BR>hr = pCP-&gt;Advise(pUnk, &amp;dwConnEvt);<BR>pCP-&gt;Release();<BR>if (FAILED(hr)) return;<BR><BR>pConn-&gt;Open("dsn=Pubs;", "sa", "", adConnectUnspecified); </TD></TR></TBODY></TABLE><BR>　　也就是说在连接(Open)之前就做这些事。<BR><BR>　　(4). 停止响应通知事件<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD>pConn-&gt;Close();<BR>// Stop using the Connection events<BR>hr = pConn-&gt;QueryInterface(__uuidof(IConnectionPointContainer), <BR>(void **) &amp;pCPC);<BR>if (FAILED(hr)) return;<BR>hr = pCPC-&gt;FindConnectionPoint(__uuidof(ConnectionEvents), &amp;pCP);<BR>pCPC-&gt;Release();<BR>if (FAILED(hr)) return rc;<BR>hr = pCP-&gt;Unadvise( dwConnEvt );<BR>pCP-&gt;Release();<BR>if (FAILED(hr)) return;</TD></TR></TBODY></TABLE><BR>　　在连接关闭之后做这件事。 </SPAN></SPAN></DIV><img src ="http://www.cppblog.com/ivenher/aggbug/2293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-12-30 18:31 <a href="http://www.cppblog.com/ivenher/articles/2293.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>_variant_t 到　CString 转换</title><link>http://www.cppblog.com/ivenher/articles/2289.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Fri, 30 Dec 2005 08:45:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2289.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2289.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2289.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2289.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2289.html</trackback:ping><description><![CDATA[<FONT size=2><FONT color=#333333><FONT face=宋体>数据类型转换函数<SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></FONT></FONT></FONT>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial">CString CZjyDlg::VariantToString(VARIANT var)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial">CString strValue;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>_variant_t var_t;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>_bstr_t bstr_t;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>time_t cur_time;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>CTime time_value;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>COleCurrency var_currency;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>switch(var.vt)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_EMPTY:<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_NULL:strValue=_T("");break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_UI1:strValue.Format("%d",var.bVal);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_I2:strValue.Format("%d",var.iVal);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_I4:strValue.Format("%d",var.lVal);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_R4:strValue.Format("%f",var.fltVal);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_R8:strValue.Format("%f",var.dblVal);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_CY:<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>var_currency=var;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>strValue=var_currency.Format(0);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_BSTR:<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>var_t =var;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>bstr_t=var_t;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>strValue.Format("%s",(const char *)bstr_t);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_DATE:<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>cur_time=var.date;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>time_value=cur_time;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>strValue.Format("%A,%B,%d,%Y");break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>case VT_BOOL:strValue.Format("%d",var.boolVal);break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>default:strValue=_T("");break;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>return strValue;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial">}<o:p></o:p></SPAN></P><img src ="http://www.cppblog.com/ivenher/aggbug/2289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-12-30 16:45 <a href="http://www.cppblog.com/ivenher/articles/2289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ado  出错处理</title><link>http://www.cppblog.com/ivenher/articles/2150.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Mon, 26 Dec 2005 12:13:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2150.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2150.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2150.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2150.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2150.html</trackback:ping><description><![CDATA[//出错处理：<BR>3127——没有找到目标表<BR>3092——目标表已经存在<BR>例如：<BR>catch(const&nbsp;_com_error&nbsp;e)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox(e.Description());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;errorCode=e.WCode();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(3127==errorCode)&nbsp;AfxMessageBox("表不存在");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(3092==errorCode)&nbsp;AfxMessageBox("表已经存在");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;FALSE;<BR>}&nbsp;<BR><img src ="http://www.cppblog.com/ivenher/aggbug/2150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-12-26 20:13 <a href="http://www.cppblog.com/ivenher/articles/2150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用ADO操作数据库的方法步骤</title><link>http://www.cppblog.com/ivenher/articles/2149.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Mon, 26 Dec 2005 11:37:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2149.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2149.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2149.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2149.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2149.html</trackback:ping><description><![CDATA[用ADO操作数据库的方法步骤<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>/***********************ADO接口简介 ***********************************/<BR>ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。 <BR><BR>_ConnectionPtr接口返回一个记录集或一个空指针。<BR>通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句，如一个存储过程。<BR>使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。<BR>通常同Cdatabase一样，使用它创建一个数据连接，然后使用其它对象执行数据输入输出操作。<BR><BR>_CommandPtr接口返回一个记录集。<BR>它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。<BR>在使用_CommandPtr接口时，你可以利用全局_ConnectionPtr接口，也可以在_CommandPtr接口里直接使用连接串。<BR>如果你只执行一次或几次数据访问操作，后者是比较好的选择。<BR>但如果你要频繁访问数据库，并要返回很多记录集，那么，你应该使用全局_ConnectionPtr接口创建一个数据连接，<BR>然后使用_CommandPtr接口执行存储过程和SQL语句。<BR><BR><BR>_RecordsetPtr是一个记录集对象。<BR>与以上两种对象相比，它对记录集提供了更多的控制功能，如记录锁定，游标控制等<BR>。同_CommandPtr接口一样，它不一定要使用一个已经创建的数据连接，<BR>可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量，让它自己创建数据连接。<BR>如果你要使用多个记录集，最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口<BR>，然后使用_RecordsetPtr执行存储过程和SQL语句。<BR><BR><BR>/***********************基本流程***********************************/<BR>(1)初始化COM库，引入ADO库定义文件<BR>(2)用Connection对象连接数据库<BR>(3)利用建立好的连接，通过Connection、Command对象执行SQL命令，或利用Recordset对象取得结果记<BR>&nbsp;&nbsp; 录集进行查询、处理。<BR>(4)使用完毕后关闭连接释放对象。<BR><BR><BR><BR>/***********************【1】COM库的初始化***********************************/<BR>我们可以使用AfxOleInit()来初始化COM库，这项工作通常在CWinApp::InitInstance()的重载函数中完<BR>成，请看如下代码:<BR><BR>BOOL CADOTest1App::InitInstance()<BR>{<BR>&nbsp;&nbsp;AfxOleInit();<BR>&nbsp;&nbsp;...... <BR>}<BR><BR><BR>/*****************【2】用#import指令引入ADO类型库**********************/<BR>我们在stdafx.h中加入如下语句：<BR>#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")<BR>其最终作用同我们熟悉的#include类似,编译的时候系统会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。<BR><BR><BR><BR>/***************【3】创建Connection对象并连接数据库********************/<BR><BR>首先我们需要添加一个指向Connection对象的指针:<BR><BR>_ConnectionPtr m_pConnection;<BR><BR>BOOL CADOTest1Dlg::OnInitDialog()<BR>{<BR>CDialog::OnInitDialog();<BR>try<BR>{<BR>&nbsp;&nbsp;HRESULT hr = m_pConnection.CreateInstance("ADODB.Connection");//创建Connection对象<BR>&nbsp;&nbsp;if(SUCCEEDED(hr))<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp; hr = m_pConnection-&gt;Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb","","",adModeUnknown);//连接数据库<BR>&nbsp;&nbsp; //上面一句中连接字串中的Provider是针对ACCESS2000环境的，对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>}<BR>catch (_com_error e) //COM错误取得,当执行COM功能的时候，如果出错，可以捕捉到_com_error的异常<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;<FONT color=#006400>CString strComError;<BR>&nbsp;&nbsp;strComError.Format("错误编号: %08lx\n错误信息: %s\n错误源: %s\n错误描述: %s",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Error(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 错误编号<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.ErrorMessage(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 错误信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (LPCSTR) e.Source(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 错误源<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (LPCSTR) e.Description());&nbsp;&nbsp;// 错误描述</FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION);<BR>}<BR>}<BR>也可以使用UDL文件进行连接。<BR>try<BR>{&nbsp;&nbsp;<BR>m_pConnection.CreateInstance(__uuidof(Connection));&nbsp;&nbsp; <BR>m_pConnection-&gt;ConnectionString ="File Name=e.udl"; <BR>m_pConnection-&gt;Open("","","",NULL); <BR>}<BR>catch(_com_error e)<BR>{....}<BR><BR>◆在这段代码中我们是通过Connection对象的Open方法来进行连接数据库的，下面是该方法的原型<BR><BR>HRESULT Connection15::Open (_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options )<BR><BR>ConnectionString 为连接字串,<BR>UserID&nbsp;&nbsp;&nbsp;&nbsp;是用户名, <BR>Password&nbsp;&nbsp; 是登陆密码,<BR>Options&nbsp;&nbsp;&nbsp;&nbsp;是连接选项,用于指定Connection对象对数据的更新许可权, <BR>&nbsp;&nbsp;&nbsp;&nbsp; Options可以是如下几个常量:<BR><BR>&nbsp;&nbsp;adModeUnknown:&nbsp;&nbsp; 缺省。当前的许可权未设置<BR>&nbsp;&nbsp;adModeRead:&nbsp;&nbsp;&nbsp;&nbsp;只读<BR>&nbsp;&nbsp;adModeWrite:&nbsp;&nbsp; 只写<BR>&nbsp;&nbsp;adModeReadWrite:&nbsp;&nbsp;可以读写<BR>&nbsp;&nbsp;adModeShareDenyRead: 阻止其它Connection对象以读权限打开连接<BR>&nbsp;&nbsp;adModeShareDenyWrite: 阻止其它Connection对象以写权限打开连接<BR>&nbsp;&nbsp;adModeShareExclusive: 阻止其它Connection对象打开连接<BR>&nbsp;&nbsp;adModeShareDenyNone: 允许其它程序或对象以任何权限建立连接<BR><BR><BR>◆常用的数据库连接方法：<BR><BR>(1)通过JET数据库引擎对ACCESS2000数据库的连接<BR>m_pConnection-&gt;Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdb","","",adModeUnknown);<BR><BR>(2)通过DSN数据源对任何支持ODBC的数据库进行连接:<BR>m_pConnection-&gt;Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);<BR>//m_pConnection-&gt;Open("DSN=test;","","",0);&nbsp;&nbsp; //连接叫作test的ODBC数据源 <BR><BR>(3)不通过DSN对SQL SERVER数据库进行连接： <BR>m_pConnection-&gt;Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139","","",adModeUnknown);<BR>其中Server是SQL服务器的名称，DATABASE是库的名称<BR><BR>◆先介绍Connection对象中两个有用的属性ConnectionTimeOut与State<BR>ConnectionTimeOut用来设置连接的超时时间，需要在Open之前调用，例如:<BR>&nbsp;&nbsp;m_pConnection-&gt;ConnectionTimeout = 5; //设置超时时间为5秒<BR>&nbsp;&nbsp;m_pConnection-&gt;Open("Data Source=adotest;","","",adModeUnknown);<BR><BR>State属性指明当前Connection对象的状态，0表示关闭，1表示已经打开，我们可以通过<BR>读取这个属性来作相应的处理，例如:<BR>if(m_pConnection-&gt;State)<BR>&nbsp;&nbsp;m_pConnection-&gt;Close(); //如果已经打开了连接则关闭它<BR><BR><BR><BR><BR>4】/*****************执行SQL命令并取得结果记录集****************/<BR><BR>为了取得结果记录集，我们定义一个指向Recordset对象的指针:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_RecordsetPtr m_pRecordset;<BR>并为其创建Recordset对象的实例:&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset.CreateInstance("ADODB.Recordset");<BR><BR>SQL命令的执行可以采用多种形式，下面我们一进行阐述。<BR><BR>◆(1)利用Connection对象的Execute方法执行SQL命令<BR>Execute方法的原型如下所示:<BR><BR>_RecordsetPtr Connection15::Execute (_bstr_t CommandText, VARIANT * RecordsAffected, long Options ) <BR>其中<BR>&nbsp;&nbsp;CommandText&nbsp;&nbsp; 是命令字串，通常是SQL命令。<BR>&nbsp;&nbsp;RecordsAffected&nbsp;&nbsp;是操作完成后所影响的行数, <BR>&nbsp;&nbsp;Options&nbsp;&nbsp;&nbsp;&nbsp;表示CommandText中内容的类型，Options可以取如下值之一：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adCmdText:&nbsp;&nbsp;表明CommandText是文本命令<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adCmdTable:&nbsp;&nbsp;表明CommandText是一个表名<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adCmdProc:&nbsp;&nbsp;表明CommandText是一个存储过程<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adCmdUnknown: 未知<BR><BR>Execute执行完后返回一个指向记录集的指针，下面我们给出具体代码并作说明。&nbsp;&nbsp;<BR>try<BR>{<BR>_variant_t ra;<BR><BR>m_pConnection-&gt;Execute("CREATE TABLE 学生信息(学号 INTEGER,姓名 TEXT,年龄 INTEGER,生日 DATETIME)",&amp;ra,adCmdText);<BR>m_pConnection-&gt;Execute("INSERT INTO 学生信息(学号,姓名,年龄,生日) VALUES (112105, '程红秀',22,'1982-08-16')",&amp;ra,adCmdText);//往表格里面添加记录<BR>m_pRecordset = m_pConnection-&gt;Execute("SELECT COUNT(*) FROM 学生信息",&amp;ra,adCmdText);&nbsp;&nbsp; //执行SQL统计命令得到包含记录条数的记录集<BR><BR>_variant_t vCount = m_pRecordset-&gt;GetCollect((_variant_t)(long)(0)); //取得第一个字段的值放入vCount变量<BR><BR>m_pRecordset-&gt;Close(); <BR>CString message;<BR>message.Format("共有%d条记录",vCount.lVal);<BR>AfxMessageBox(message);&nbsp;&nbsp; <BR>}<BR><BR>catch (_com_error e) <BR>{ ...}<BR><BR><BR><BR>◆(2)利用 Command对象 来执行SQL命令<BR>try<BR>{<BR>&nbsp;&nbsp;_CommandPtr m_pCommand; <BR>&nbsp;&nbsp;m_pCommand.CreateInstance("ADODB.Command");<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;m_pCommand-&gt;ActiveConnection = m_pConnection; //关键的一句，将建立的连接赋值给它<BR><BR>&nbsp;&nbsp;m_pCommand-&gt;CommandText="INSERT INTO 学生信息(学号,姓名,年龄,生日) VALUES (112105, '程红秀',22,'1982-08-16')";<BR>&nbsp;&nbsp;m_pCommand-&gt;Execute(NULL,NULL,adCmdText);<BR><BR>&nbsp;&nbsp;m_pCommand-&gt;CommandText="SELECT COUNT(*) FROM 学生信息";<BR>&nbsp;&nbsp;m_pRecordset=m_pCommand-&gt;Execute(NULL,NULL,adCmdText);<BR><BR>&nbsp;&nbsp;_variant_t vCount = m_pRecordset-&gt;GetCollect((_variant_t)(long)0); //取得第一个字段的值<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;CString str;<BR>&nbsp;&nbsp;str.Format("共有%d条记录",vCount.lVal);<BR>&nbsp;&nbsp;AfxMessageBox(str);&nbsp;&nbsp; <BR><BR>&nbsp;&nbsp;m_pRecordset-&gt;Close(); <BR><BR>}<BR>catch (_com_error e) {...}<BR><BR>在这段代码中我们只是用Command对象来执行了SELECT查询语句，<BR>Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 <BR><BR><BR>◆(3)直接用Recordset对象进行查询取得记录集 <BR>例如 <BR>&nbsp;&nbsp;m_pRecordset-&gt;Open("SELECT * FROM 学生信息",_variant_t((IDispatch *)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);<BR><BR>Open方法的原型是这样的:<BR>HRESULT Recordset15::Open ( const _variant_t &amp; Source, const _variant_t &amp; ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options ) <BR>其中：<BR>①Source是数据查询字符串<BR>②ActiveConnection是已经建立好的连接（我们需要用Connection对象指针来构造一个_variant_t对象) <BR>③CursorType光标类型，它可以是以下值之一,请看这个枚举结构:<BR>&nbsp;&nbsp; enum CursorTypeEnum<BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;adOpenUnspecified = -1, //不作特别指定<BR>&nbsp;&nbsp;&nbsp;&nbsp;adOpenForwardOnly = 0, //前滚静态光标。这种光标只能向前浏览记录集，比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用<BR>&nbsp;&nbsp;&nbsp;&nbsp;adOpenKeyset = 1,&nbsp;&nbsp;//采用这种光标的记录集看不到其它用户的新增、删除操作，但对于更新原有记录的操作对你是可见的。<BR>&nbsp;&nbsp;&nbsp;&nbsp;adOpenDynamic = 2,&nbsp;&nbsp;//动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。<BR>&nbsp;&nbsp;&nbsp;&nbsp;adOpenStatic = 3&nbsp;&nbsp;//静态光标。它为你的记录集产生一个静态备份，但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。<BR>&nbsp;&nbsp; };<BR>④LockType锁定类型，它可以是以下值之一，请看如下枚举结构：<BR>&nbsp;&nbsp; enum LockTypeEnum<BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;adLockUnspecified = -1,&nbsp;&nbsp;//未指定<BR>&nbsp;&nbsp;&nbsp;&nbsp;adLockReadOnly = 1,&nbsp;&nbsp; //只读记录集<BR>&nbsp;&nbsp;&nbsp;&nbsp;adLockPessimistic = 2,&nbsp;&nbsp;//悲观锁定方式。数据在更新时锁定其它所有动作，这是最安全的锁定机制<BR>&nbsp;&nbsp;&nbsp;&nbsp;adLockOptimistic = 3,&nbsp;&nbsp;//乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作<BR>&nbsp;&nbsp;&nbsp;&nbsp;adLockBatchOptimistic = 4， //乐观分批更新。编辑时记录不会锁定，更改、插入及删除是在批处理模式下完成。<BR>&nbsp;&nbsp; }; <BR>⑤Options请参考本文中对Connection对象的Execute方法的介绍<BR><BR><BR><BR><BR>/***********************【5】记录集的遍历、更新*************************/<BR><BR>根据我们刚才通过执行SQL命令建立好的 学生信息 表，它包含四个字段:学号，姓名，年龄，生日<BR>以下的代码实现：打开记录集，遍历所有记录，删除第一条记录，添加三条记录，移动光标到第二条<BR>记录，更改其年龄，保存到数据库。<BR><BR>try<BR>{<BR>&nbsp;&nbsp;_variant_t vUsername,vBirthday,vID,vOld;<BR>&nbsp;&nbsp;_RecordsetPtr m_pRecordset;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;m_pRecordset.CreateInstance("ADODB.Recordset");<BR>&nbsp;&nbsp;m_pRecordset-&gt;Open("SELECT * FROM 学生信息",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;while(!m_pRecordset-&gt;adoEOF) <BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp; vID = m_pRecordset-&gt;GetCollect(_variant_t((long)0));&nbsp;&nbsp;&nbsp;&nbsp;//取得第1列的值,从0开始计数，你也可以直接给出列的名称，如下一行<BR>&nbsp;&nbsp; vUsername = m_pRecordset-&gt;GetCollect("姓名");&nbsp;&nbsp;//取得姓名字段的值<BR>&nbsp;&nbsp; vOld = m_pRecordset-&gt;GetCollect("年龄");<BR>&nbsp;&nbsp; vBirthday = m_pRecordset-&gt;GetCollect("生日");<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",<BR>&nbsp;&nbsp;&nbsp;&nbsp;vID.lVal,<BR>&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)(_bstr_t)vUsername,<BR>&nbsp;&nbsp;&nbsp;&nbsp;vOld.lVal,<BR>&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)(_bstr_t)vBirthday);&nbsp;&nbsp;//在DEBUG方式下的OUTPUT窗口输出记录集中的记录<BR><BR>&nbsp;&nbsp; m_pRecordset-&gt;MoveNext();&nbsp;&nbsp;&nbsp;&nbsp;//移到下一条记录<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;m_pRecordset-&gt;MoveFirst();&nbsp;&nbsp;&nbsp;&nbsp;//移到首条记录<BR>&nbsp;&nbsp;m_pRecordset-&gt;Delete(adAffectCurrent);&nbsp;&nbsp;&nbsp;&nbsp;//删除当前记录<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;for(int i=0;i&lt;3;i++)&nbsp;&nbsp;&nbsp;&nbsp;//添加三条新记录并赋值<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp; m_pRecordset-&gt;AddNew();&nbsp;&nbsp;&nbsp;&nbsp;//添加新记录<BR>&nbsp;&nbsp; m_pRecordset-&gt;PutCollect("学号",_variant_t((long)(i+10)));<BR>&nbsp;&nbsp; m_pRecordset-&gt;PutCollect("姓名",_variant_t("王斌年"));<BR>&nbsp;&nbsp; m_pRecordset-&gt;PutCollect("年龄",_variant_t((long)21));<BR>&nbsp;&nbsp; m_pRecordset-&gt;PutCollect("生日",_variant_t("1930-3-15"));<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;m_pRecordset-&gt;Move(1,_variant_t((long)adBookmarkFirst));&nbsp;&nbsp;&nbsp;&nbsp;//从第一条记录往下移动一条记录,即移动到第二条记录处<BR>&nbsp;&nbsp;m_pRecordset-&gt;PutCollect(_variant_t("年龄"),_variant_t((long)45));&nbsp;&nbsp;&nbsp;&nbsp;//修改其年龄<BR>&nbsp;&nbsp;m_pRecordset-&gt;Update();&nbsp;&nbsp;&nbsp;&nbsp;//保存到库中<BR>&nbsp;&nbsp;<BR>} catch (_com_error e){}<BR><BR><BR><BR>/***********************【6】关闭记录集与连接 *************************/<BR>记录集或连接都可以用Close方法来关闭&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>m_pRecordset-&gt;Close(); //关闭记录集&nbsp;&nbsp;<BR>m_pConnection-&gt;Close(); //关闭连接 <BR><BR><BR><BR><BR>在stdafx.h中进行宏定义:<BR>#if !defined CATCH_ERROR<BR>#define CATCH_ERROR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<BR>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<BR>&nbsp;&nbsp; CString strComError;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<BR>&nbsp;&nbsp; strComError.Format("错误编号: %08lx\n错误信息: %s\n错误源: %s\n错误描述: %s", \<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.Error(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.ErrorMessage(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCSTR) e.Source(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCSTR) e.Description());&nbsp;&nbsp;\<BR>&nbsp;&nbsp; ::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION); \<BR>&nbsp;&nbsp;}<BR>#endif<BR>使用方法：<BR>try<BR>{&nbsp;&nbsp;...}<BR>catch(_com_error e)<BR>{<BR>CATCH_ERROR;<BR>}<BR><img src ="http://www.cppblog.com/ivenher/aggbug/2149.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-12-26 19:37 <a href="http://www.cppblog.com/ivenher/articles/2149.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ADO数据库编程入门</title><link>http://www.cppblog.com/ivenher/articles/1773.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 15 Dec 2005 03:03:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/1773.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/1773.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/1773.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/1773.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/1773.html</trackback:ping><description><![CDATA[ADO 是目前在Windows环境中比较流行的客户端数据库编程技术。ADO是建立在OLE DB底层技术之上的高级编程接口，因而它兼具有强大的数据处理功能（处理各种不同类型的数据源、分布式的数据处理等等）和极其简单、易用的编程接口，因而得到了广泛的应用。而且按微软公司的意图，OLE DB和ADO将逐步取代 ODBC和DAO。现在介绍ADO各种应用的文章和书籍有很多，本文着重站在初学者的角度，简要探讨一下在VC++中使用ADO编程时的一些问题。我们希望阅读本文之前，您对ADO技术的基本原理有一些了解。<BR>一、在VC++中使用ADO编程<BR>ADO实际上就是由一组Automation对象构成的组件，因此可以象使用其它任何Automation对象一样使用ADO。ADO中最重要的对象有三个：Connection、Command和Recordset，它们分别表示连接对象、命令对象和记录集对象。如果您熟悉使用MFC中的ODBC类（CDatabase、CRecordset)编程，那么学习ADO编程就十分容易了。<BR>使用ADO编程时可以采用以下三种方法之一：<BR>1、使用预处理指令#import<BR>#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \<BR>&nbsp;&nbsp; no_namespace rename("EOF", "EndOfFile")<BR>但要注意不能放在stdAfx.h文件的开头，而应该放在所有include指令的后面。否则在编译时会出错。<BR>程序在编译过程中，VC++会读出msado15.dll中的类型库信息，自动产生两个该类型库的头文件和实现文件msado15.tlh和msado15.tli（在您的Debug或Release目录下）。在这两个文件里定义了ADO的所有对象和方法，以及一些枚举型的常量等。我们的程序只要直接调用这些方法就行了，与使用MFC中的COleDispatchDriver类调用Automation对象十分类似。<BR>2、使用MFC中的CIDispatchDriver<BR>就是通过读取msado15.dll中的类型库信息，建立一个COleDispatchDriver类的派生类，然后通过它调用ADO对象。<BR>3、直接用COM提供的API<BR>&nbsp;如使用如下代码：<BR>&nbsp;CLSID clsid;<BR>&nbsp;HRESULT hr = ::CLSIDFromProgID(L"ADODB.Connection", &amp;clsid);<BR>&nbsp;if(FAILED(hr))<BR>&nbsp;{...}<BR>&nbsp;::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IDispatch, (void **)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;pDispatch);<BR>&nbsp;if(FAILED(hr))<BR>&nbsp;{...}<BR>以上三种方法，第一和第二种类似，可能第一种好用一些，第三种编程可能最麻烦。但可能第三种方法也是效率最高的，程序的尺寸也最小，并且对ADO的控制能力也最强。<BR>据微软资料介绍，第一种方法不支持方法调用中的默认参数，当然第二种方法也是这样，但第三种就不是这样了。采用第三种方法的水平也最高。当你需要绕过ADO而直接调用OLE DB底层的方法时，就一定要使用第三种方法了。<BR>ADO编程的关键，就是熟练地运用ADO提供的各种对象(object)、方法(method)、属性(property)和容器（collection）。另外，如果是在MS SQL或Oracle等大型数据库上编程，还要能熟练使用SQL语言。<BR>二、使用#import方法的编程步骤<BR>这里建议您使用#import的方法，因为它易学、易用，代码也比较简洁。<BR>1、 添加#import指令<BR>打开stdafx.h文件，将下列内容添加到所有的include指令之后：<BR>#include &lt;icrsint.h&gt;&nbsp;&nbsp; //Include support for VC++ Extensions<BR>#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \<BR>&nbsp;&nbsp; no_namespace rename("EOF", "adoEOF")<BR>其中icrsint.h文件包含了VC++扩展的一些预处理指令、宏等的定义，用于COM编程时使用。<BR>2、定义_ConnectionPtr型变量，并建立数据库连接<BR>建立了与数据库服务器的连接后，才能进行其他有关数据库的访问和操作。ADO使用Connection对象来建立与数据库服务器的连接，所以它相当于MFC中的CDatabase类。和CDatabase类一样，调用Connection对象的Open方法即可建立与服务器的连接。<BR>数据类型&nbsp;_ConnectionPtr实际上就是由类模板_com_ptr_t而得到的一个具体的实例类，其定义可以到msado15.tlh、comdef.h 和comip.h这三个文件中找到。在msado15.tlh中有：<BR>_COM_SMARTPTR_TYPEDEF(_Collection, __uuidof(_Collection));<BR>经宏扩展后就得到了_ConnectionPtr类。_ConnectionPtr类封装了Connection对象的Idispatch接口指针，及一些必要的操作。我们就是通过这个指针来操纵Connection对象。类似地，后面用到的_CommandPtr和_RecordsetPtr类型也是这样得到的，它们分别表示命令对象指针和记录集对象的指针。<BR>（1）、连接到MS SQL Server<BR>注意连接字符串的格式，提供正确的连接字符串是成功连接到数据库服务器的第一步，有关连接字符串的详细信息参见微软MSDN Library光盘。<BR>本例连接字符串中的server_name，database_name，user_name和password在编程时都应该替换成实际的内容。<BR>&nbsp;_ConnectionPtr pMyConnect=NULL;<BR>&nbsp;HRESULT hr=pMyConnect.CreateInstance(__uuidof(Connection)));<BR>&nbsp;if(FAILED(hr))return;<BR>_bstr_t strConnect="Provider=SQLOLEDB; Server=server_name;"<BR>&nbsp;&nbsp;"Database=database_name; uid=user_name; pwd=password;";&nbsp;<BR>//connecting to the database server now:<BR>&nbsp;try{pMyConnect-&gt;Open(strConnect,"","",NULL);}<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBox(NULL,e.Description(),"警告",MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR><BR>注意Connection对象的Open方法中的连接字符串参数必须是BSTR或_bstr_t类型。另外，本例是直接通过OLE DB Provider建立连接，所以无需建立数据源。<BR>（2）、通过ODBC Driver连接到Database Server<BR>连接字符串格式与直接用ODBC编程时的差不多：<BR>_bstr_t strConnect="DSN=datasource_name; Database=database_name; uid=user_name; pwd=password;";<BR>此时与ODBC编程一样，必须先建立数据源。<BR>3、定义_RecordsetPtr型变量，并打开数据集<BR>定义_RecordsetPtr型变量，然后通过它调用Recordset对象的Open方法，即可打开一个数据集。所以Recordset对象与MFC中的CRecordset类类似，它也有当前记录、当前记录指针的概念。如：<BR>&nbsp;_RecordsetPtr m_pRecordset;<BR>&nbsp;if(!FAILED(m_pRecordset.CreateInstance( __uuidof( Recordset )))<BR>&nbsp;{<BR>&nbsp;&nbsp;m_pDoc-&gt;m_initialized=FALSE;<BR>&nbsp;&nbsp;return;<BR>&nbsp;}<BR>try{<BR>&nbsp;&nbsp;m_pRecordset-&gt;Open(_variant_t("mytable"),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _variant_t((IDispatch *)pMyConnect,true), adOpenKeyset,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adLockOptimistic, adCmdTable);<BR>&nbsp;}<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBox(NULL,"无法打开mytable表。","提示",<BR>MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>Recordset对象的Open方法非常重要，它的第一个参数可以是一个SQL语句、一个表的名字或一个命令对象等等；第二个参数就是前面建立的连接对象的指针。此外，用Connection和Command对象的Execute方法也能得到记录集，但是只读的。<BR>4、读取当前记录的数据<BR>我认为读取数据的最方便的方法如下：<BR>&nbsp;try{<BR>&nbsp;&nbsp;m_pRecordset-&gt;MoveFirst();&nbsp;&nbsp; <BR>&nbsp;&nbsp;while(m_pRecordset-&gt;adoEOF==VARIANT_FALSE)&nbsp;<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;//Retrieve column's value:&nbsp;<BR>&nbsp;&nbsp;&nbsp;CString sName=(char*)(_bstr_t)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;&nbsp;(_variant_t("name"))-&gt;Value);<BR>&nbsp;&nbsp;&nbsp;short cAge=(short)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;&nbsp;(_variant_t("age"))-&gt;Value);<BR>&nbsp;&nbsp;&nbsp;//Do something what you want to do:<BR>&nbsp;&nbsp;&nbsp;......<BR>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>&nbsp;}//try<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;CString str=(char*)e.Description();<BR>&nbsp;&nbsp;::MessageBox(NULL,str+"\n又出毛病了。","提示",<BR>MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>
<P>本例中的name和age都是字段名，读取的字段值分别保存在sName和cAge变量内。例中的Fields是Recordset对象的容器，GetItem方法返回的是Field对象，而Value则是Field对象的一个属性（即该字段的值）。通过此例，应掌握操纵对象属性的方法。例如，要获得Field 对象的Value属性的值可以直接用属性名Value来引用它（如上例），但也可以调用Get方法，例如：<BR>CString sName=(char*)(_bstr_t)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;&nbsp;(_variant_t("name"))-&gt;GetValue());<BR>从此例还可以看到，判断是否到达记录集的末尾，使用记录集的adoEOF属性，其值若为真即到了结尾，反之则未到。判断是否到达记录集开头，则可用BOF属性。<BR>另外，读取数据还有一个方法，就是定义一个绑定的类，然后通过绑定的变量得到字段值（详见后面的介绍）。<BR>5、修改数据<BR>方法一：<BR>&nbsp;try{<BR>&nbsp;&nbsp;m_pRecordset-&gt;MoveFirst();&nbsp;&nbsp; <BR>&nbsp;&nbsp;while(m_pRecordset-&gt;adoEOF==VARIANT_FALSE)&nbsp;<BR>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;&nbsp;(_variant_t("姓名"))-&gt;Value=_bstr_t("赵薇");<BR>&nbsp;&nbsp;&nbsp;......<BR>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;Update();<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>&nbsp;}//try<BR>改变了Value属性的值，即改变了字段的值。<BR>方法二：<BR>&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;&nbsp;(_variant_t("姓名"))-&gt;PutValue(_bstr_t("赵薇"));<BR>方法三：就是用定义绑定类的方法（详见后面的介绍）。<BR>6、添加记录<BR>新记录添加成功后，即自动成为当前记录。AddNew方法有两种形式，一个含有参数，而另一个则不带参数。<BR>方法一（不带参数）：<BR>&nbsp;// Add new record into this table:<BR>&nbsp;try{<BR>&nbsp;&nbsp;if(!m_pRecordset-&gt;Supports(adAddNew)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;&nbsp;m_pRecordset-&gt;AddNew();&nbsp;<BR>&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;(_variant_t("姓名"))-&gt;Value=_bstr_t("赵薇");<BR>&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;(_variant_t("性别"))-&gt;Value=_bstr_t("女");<BR>&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;(_variant_t("age"))-&gt;Value=_variant_t((short)20);<BR>&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;(_variant_t("marry"))-&gt;Value=_bstr_t("未婚");<BR>&nbsp;&nbsp;m_pRecordset-&gt;Update();&nbsp;&nbsp;<BR>&nbsp;}//try<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBox(NULL, "又出毛病了。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>这种方法弄完了还要调用Update()。<BR>方法二（带参数）：<BR>&nbsp;&nbsp;_variant_t varName[4],narValue[4];<BR>&nbsp;&nbsp;varName[0] = L"姓名";<BR>&nbsp;&nbsp;varName[1] = L"性别";<BR>&nbsp;&nbsp;varName[2] = L"age";<BR>&nbsp;&nbsp;varName[3] = L"marry";<BR>&nbsp;&nbsp;narValue[0]=_bstr_t("赵薇");<BR>&nbsp;&nbsp;narValue[1]=_bstr_t("女");<BR>&nbsp;&nbsp;narValue[2]=_variant_t((short)20);<BR>&nbsp;&nbsp;narValue[3]=_bstr_t("未婚");<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;&nbsp;const int nCrit = sizeof varName / sizeof varName[0];<BR>&nbsp;&nbsp;// Create SafeArray Bounds and initialize the array<BR>&nbsp;&nbsp;SAFEARRAYBOUND rgsaName[1],rgsaValue[1];<BR>&nbsp;&nbsp;rgsaName[0].lLbound = 0;&nbsp;&nbsp; <BR>&nbsp;&nbsp;rgsaName[0].cElements = nCrit;<BR>&nbsp;&nbsp;SAFEARRAY *psaName = SafeArrayCreate( VT_VARIANT, 1, rgsaName );<BR>&nbsp;&nbsp;rgsaValue[0].lLbound = 0;<BR>&nbsp;&nbsp;rgsaValue[0].cElements = nCrit;<BR>&nbsp;&nbsp;SAFEARRAY *psaValue = SafeArrayCreate( VT_VARIANT, 1, rgsaValue );<BR>&nbsp;&nbsp;// Set the values for each element of the array<BR>&nbsp;&nbsp;HRESULT hr1=S_OK.hr2=S_OK;<BR>&nbsp;&nbsp;for( long i = 0 ; i &lt; nCrit &amp;&amp; SUCCEEDED( hr1 ) &amp;&amp; SUCCEEDED( hr2 );i++)&nbsp;&nbsp; <BR>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;hr1=SafeArrayPutElement(psaName, &amp;i,&amp;varName[i]);<BR>&nbsp;&nbsp;&nbsp;hr2=SafeArrayPutElement(psaValue, &amp;i,&amp;narValue[i]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp;// Initialize and fill the SafeArray<BR>&nbsp;&nbsp;VARIANT vsaName,vsaValue;&nbsp;&nbsp; <BR>&nbsp;&nbsp;vsaName.vt = VT_VARIANT | VT_ARRAY;<BR>&nbsp;&nbsp;vsaValue.vt = VT_VARIANT | VT_ARRAY;<BR>&nbsp;&nbsp;V_ARRAY(&amp;vsaName) = psaName;//&amp;vsaName-&gt;parray=psaName;<BR>&nbsp;&nbsp;&nbsp;//see definition in oleauto.h file.<BR>&nbsp;&nbsp;V_ARRAY(&amp;vsaValue) = psaValue;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;// Add a new record:<BR>&nbsp;&nbsp;m_pRecordset-&gt;AddNew(vsaName,vsaValue);<BR>这种方法不需要调用Update，因为添加后，ADO会自动调用它。此方法主要是使用SafeArray挺麻烦。<BR>方法三：就是用定义绑定类的方法（详见后面的介绍）。<BR>7、删除记录<BR>调用Recordset的Delete方法就行了，删除的是当前记录。要了解Delete的其它用法请查阅参考文献。<BR>&nbsp;try{<BR>&nbsp;&nbsp;m_pRecordset-&gt;MoveFirst();&nbsp;&nbsp; <BR>&nbsp;&nbsp;while(m_pRecordset-&gt;adoEOF==VARIANT_FALSE)&nbsp;<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;CString sName=(char*)(_bstr_t)(m_pRecordset-&gt;Fields-&gt;GetItem<BR>&nbsp;&nbsp;&nbsp;&nbsp;(_variant_t("姓名"))-&gt;Value);<BR>&nbsp;&nbsp;&nbsp;if(::MessageBox(NULL,"姓名="+sName+"\n删除她吗？",<BR>&nbsp;&nbsp;&nbsp;&nbsp;"提示",MB_YESNO | MB_ICONWARNING)==IDYES)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;Delete(adAffectCurrent);&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;Update();<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>&nbsp;}//try<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBox(NULL,"又出毛病了。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>8、使用带参数的命令<BR>Command对象所代表的就是一个Provider能够理解的命令，如SQL语句等。使用Command对象的关键就是把表示命令的语句设置到CommandText属性中，然后调用Command对象的Execute方法就行了。一般情况下在命令中无需使用参数，但有时使用参数，可以增加其灵活性和效率。<BR>(1). 建立连接、命令对象和记录集对象<BR>本例中表示命令的语句就是一个SQL语句（SELECT语句）。SELECT语句中的问号?就代表参数，如果要多个参数，就多放几个问号，每个问号代表一个参数。<BR>_ConnectionPtr&nbsp; Conn1;<BR>_CommandPtr&nbsp;&nbsp;&nbsp;&nbsp; Cmd1;<BR>ParametersPtr&nbsp;&nbsp; *Params1 = NULL;&nbsp;&nbsp; // Not an instance of a smart pointer.<BR>_ParameterPtr&nbsp;&nbsp; Param1;<BR>_RecordsetPtr&nbsp;&nbsp; Rs1;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>try<BR>{<BR>&nbsp;// Create Connection Object (1.5 Version)<BR>&nbsp;Conn1.CreateInstance( __uuidof( Connection ) );<BR>&nbsp;Conn1-&gt;ConnectionString = bstrConnect;<BR>&nbsp;&nbsp;&nbsp; Conn1-&gt;Open( bstrEmpty, bstrEmpty, bstrEmpty, -1 );<BR>&nbsp;&nbsp;&nbsp; // Create Command Object<BR>&nbsp;&nbsp;&nbsp; Cmd1.CreateInstance( __uuidof( Command ) );<BR>&nbsp;&nbsp;&nbsp; Cmd1-&gt;ActiveConnection = Conn1;<BR>&nbsp;&nbsp;&nbsp; Cmd1-&gt;CommandText&nbsp; = _bstr_t("SELECT * FROM mytable WHERE age&lt; ?");<BR>}//try<BR>要注意命令对象必须与连接对象关联起来才能起作用，本例中将命令对象的ActiveConnection属性设置为连接对象的指针，即为此目的：<BR>Cmd1-&gt;ActiveConnection = Conn1;<BR>&nbsp;(2). 创建参数对象，并给参数赋值<BR>// Create Parameter Object<BR>Param1 = Cmd1-&gt;CreateParameter( _bstr_t(bstrEmpty),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adInteger,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adParamInput,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -1,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _variant_t( (long) 5) );<BR>Param1-&gt;Value = _variant_t( (long) 5 );<BR>Cmd1-&gt;Parameters-&gt;Append( Param1 );<BR>用命令对象的方法来创建一个参数对象，其中的长度参数（第三个）如果是固定长度的类型，就填-1，如果是字符串等可变长度的就填其实际长度。Parameters是命令对象的一个容器，它的Append方法就是把创建的参数对象追加到该容器里。Append进去的参数按先后顺序与SQL语句中的问号从左至右一一对应。<BR>(3). 执行命令打开记录集<BR>// Open Recordset Object<BR>Rs1 = Cmd1-&gt;Execute( &amp;vtEmpty, &amp;vtEmpty2, adCmdText );<BR>但要注意，用Command和Connection对象的Execute方法得到的Recordset是只读的。因为在打开Recordset之前，我们无法设置它的LockType属性（其默认值为只读）。而在打开之后设置LockType不起作用。<BR>我发现用上述方法得到记录集Rs1后，不但Rs1中的记录无法修改，即使直接用SQL语句修改同一表中任何记录都不行。<BR>要想能修改数据，还是要用Recordset自己的Open方法才行，如：<BR>&nbsp;try{<BR>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;Open((IDispatch *) Cmd1, vtMissing,<BR>&nbsp;&nbsp;&nbsp;&nbsp;adOpenStatic, adLockOptimistic, adCmdUnspecified);<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;catch (_com_error &amp;e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;::MessageBox(NULL,"mytable表不存在。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;&nbsp;}<BR>Recordset对象的Open方法真是太好了，其第一个参数可以是SQL语句、表名字、命令对象指针等等。<BR>9、响应ADO的通知事件<BR>通知事件就是当某个特定事件发生时，由Provider通知客户程序，换句话说，就是由Provider调用客户程序中的一个特定的方法（即事件的处理函数）。所以为了响应一个事件，最关键的就是要实现事件的处理函数。<BR>(1). 从ConnectionEventsVt接口派生出一个类<BR>为了响应_Connection的通知事件，应该从ConnectionEventsVt接口派生出一个类：<BR>class CConnEvent : public ConnectionEventsVt<BR>{<BR>private:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULONG&nbsp;&nbsp; m_cRef;<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CConnEvent() { m_cRef = 0; };<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~CConnEvent() {};<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STDMETHODIMP_(ULONG) AddRef(void);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STDMETHODIMP_(ULONG) Release(void);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STDMETHODIMP raw_InfoMessage( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Error *pError,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventStatusEnum *adStatus,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct _Connection *pConnection);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STDMETHODIMP raw_BeginTransComplete( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LONG TransactionLevel,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Error *pError,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventStatusEnum *adStatus,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct _Connection *pConnection);<BR>&nbsp;&nbsp;......<BR>};<BR>(2). 实现每一个事件的处理函数(凡是带raw_前缀的方法都把它实现了)：<BR>STDMETHODIMP CConnEvent::raw_InfoMessage( <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Error *pError,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventStatusEnum *adStatus,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct _Connection *pConnection)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *adStatus = adStatusUnwantedEvent;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>有些方法虽然你并不需要，但也必须实现它，只需简单地返回一个S_OK即可。但如果要避免经常被调用，还应在其中将adStatus参数设置为adStatusUnwantedEvent，则在本次调用后，以后就不会被调用了。<BR>另外还必须实现QueryInterface, AddRef, 和Release三个方法:&nbsp;<BR>&nbsp;STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv) <BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ppv = NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (riid == __uuidof(IUnknown) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; riid == __uuidof(ConnectionEventsVt)) *ppv = this;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (*ppv == NULL)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ResultFromScode(E_NOINTERFACE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AddRef();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NOERROR;<BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp; STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; };<BR>&nbsp;&nbsp; STDMETHODIMP_(ULONG) CConnEvent::Release()<BR>{ <BR>if (0 != --m_cRef) return m_cRef;<BR>delete this;<BR>return 0;<BR>}<BR>(3). 开始响应通知事件<BR>&nbsp;// Start using the Connection events<BR>&nbsp;IConnectionPointContainer&nbsp;&nbsp; *pCPC = NULL;<BR>&nbsp;IConnectionPoint&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pCP = NULL;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;hr = pConn.CreateInstance(__uuidof(Connection));<BR>&nbsp;&nbsp; if (FAILED(hr)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;hr = pConn-&gt;QueryInterface(__uuidof(IConnectionPointContainer), <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void **)&amp;pCPC);<BR>&nbsp;if (FAILED(hr)) return;<BR>&nbsp;hr = pCPC-&gt;FindConnectionPoint(__uuidof(ConnectionEvents), &amp;pCP);<BR>&nbsp;pCPC-&gt;Release();<BR>&nbsp;if (FAILED(hr)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;pConnEvent = new CConnEvent();<BR>&nbsp;&nbsp; hr = pConnEvent-&gt;QueryInterface(__uuidof(IUnknown), (void **) &amp;pUnk);<BR>&nbsp;&nbsp; if (FAILED(hr)) return rc; <BR>&nbsp;&nbsp; hr = pCP-&gt;Advise(pUnk, &amp;dwConnEvt);<BR>&nbsp;&nbsp; pCP-&gt;Release();<BR>&nbsp;&nbsp; if (FAILED(hr)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;pConn-&gt;Open("dsn=Pubs;", "sa", "", adConnectUnspecified); <BR>也就是说在连接(Open)之前就做这些事。<BR>(4). 停止响应通知事件<BR>&nbsp;pConn-&gt;Close();<BR>&nbsp;// Stop using the Connection events<BR>&nbsp; hr = pConn-&gt;QueryInterface(__uuidof(IConnectionPointContainer), <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void **) &amp;pCPC);<BR>&nbsp;&nbsp; if (FAILED(hr)) return;<BR>&nbsp;&nbsp; hr = pCPC-&gt;FindConnectionPoint(__uuidof(ConnectionEvents), &amp;pCP);<BR>&nbsp;&nbsp; pCPC-&gt;Release();<BR>&nbsp;&nbsp; if (FAILED(hr)) return rc;<BR>&nbsp;&nbsp; hr = pCP-&gt;Unadvise( dwConnEvt );<BR>&nbsp;&nbsp; pCP-&gt;Release();<BR>&nbsp;&nbsp; if (FAILED(hr)) return;<BR>在连接关闭之后做这件事。 <BR>10、邦定数据<BR>定义一个绑定类，将其成员变量绑定到一个指定的记录集，以方便于访问记录集的字段值。<BR>(1). 从CADORecordBinding派生出一个类：<BR>class CCustomRs : public CADORecordBinding<BR>{<BR>BEGIN_ADO_BINDING(CCustomRs)<BR>&nbsp;&nbsp; ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(m_szau_fname), lau_fnameStatus, false)<BR>&nbsp;&nbsp; ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(m_szau_lname), lau_lnameStatus, false)<BR>&nbsp;&nbsp; ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_szphone,&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(m_szphone),&nbsp;&nbsp;&nbsp; lphoneStatus,&nbsp;&nbsp;&nbsp; true)<BR>END_ADO_BINDING()<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>public:<BR>&nbsp;&nbsp; CHAR&nbsp;&nbsp; m_szau_fname[22];<BR>&nbsp;&nbsp; ULONG&nbsp;&nbsp; lau_fnameStatus;<BR>&nbsp;&nbsp; CHAR&nbsp;&nbsp; m_szau_lname[42];<BR>&nbsp;&nbsp; ULONG&nbsp;&nbsp; lau_lnameStatus;<BR>&nbsp;&nbsp; CHAR&nbsp;&nbsp; m_szphone[14];<BR>&nbsp;&nbsp; ULONG&nbsp;&nbsp; lphoneStatus;<BR>};<BR>其中将要绑定的字段与变量名用BEGIN_ADO_BINDING宏关联起来。每个字段对应于两个变量，一个存放字段的值，另一个存放字段的状态。字段用从1开始的序号表示，如1，2，3等等。<BR>特别要注意的是：如果要绑定的字段是字符串类型，则对应的字符数组的元素个数一定要比字段长度大2（比如m_szau_fname[22]，其绑定的字段au_fname的长度实际是20），不这样绑定就会失败。我分析多出的2可能是为了存放字符串结尾的空字符null和BSTR字符串开头的一个字（表示BSTR的长度）。这个问题对于初学者来说可能是一个意想不到的问题。<BR>CADORecordBinding类的定义在icrsint.h文件里，内容是：<BR>class CADORecordBinding<BR>{<BR>public:<BR>&nbsp;STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) PURE;<BR>};<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>BEGIN_ADO_BINDING宏的定义也在icrsint.h文件里，内容是：<BR>#define BEGIN_ADO_BINDING(cls) public: \<BR>typedef cls ADORowClass; \<BR>const ADO_BINDING_ENTRY* STDMETHODCALLTYPE GetADOBindingEntries() { \<BR>static const ADO_BINDING_ENTRY rgADOBindingEntries[] = { <FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>ADO_VARIABLE_LENGTH_ENTRY2宏的定义也在icrsint.h文件里：<BR>#define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)\<BR>&nbsp;{Ordinal, \<BR>&nbsp;DataType, \<BR>&nbsp;0, \<BR>&nbsp;0, \<BR>&nbsp;Size, \<BR>&nbsp;offsetof(ADORowClass, Buffer), \<BR>&nbsp;offsetof(ADORowClass, Status), \<BR>&nbsp;0, \<BR>&nbsp;classoffset(CADORecordBinding, ADORowClass), \<BR>&nbsp;Modify},<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;#define END_ADO_BINDING宏的定义也在icrsint.h文件里：<BR>&nbsp;#define END_ADO_BINDING()&nbsp;&nbsp; {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\<BR>&nbsp;return rgADOBindingEntries;}<BR>(2). 绑定<BR>_RecordsetPtr&nbsp;&nbsp; Rs1;<BR>IADORecordBinding&nbsp;&nbsp; *picRs=NULL;<BR>CCustomRs rs;<BR>......<BR>Rs1-&gt;QueryInterface(__uuidof(IADORecordBinding), <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (LPVOID*)&amp;picRs));<BR>picRs-&gt;BindToRecordset(&amp;rs);<BR>派生出的类必须通过IADORecordBinding接口才能绑定，调用它的BindToRecordset方法就行了。<BR>(3). rs中的变量即是当前记录字段的值<BR>//Set sort and filter condition:<BR>// Step 4: Manipulate the data<BR>Rs1-&gt;Fields-&gt;GetItem("au_lname")-&gt;Properties-&gt;GetItem("Optimize")-&gt;Value = true; <BR>Rs1-&gt;Sort = "au_lname ASC";<BR>Rs1-&gt;Filter = "phone LIKE '415 5*'";<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>Rs1-&gt;MoveFirst();<BR>while (VARIANT_FALSE == Rs1-&gt;EndOfFile)<BR>{<BR>&nbsp;printf("Name: %s\t %s\tPhone: %s\n",&nbsp; <BR>&nbsp;&nbsp;(rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : ""), <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : ""),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (rs.lphoneStatus == adFldOK ? rs.m_szphone&nbsp;&nbsp; : ""));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rs.lphoneStatus == adFldOK)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(rs.m_szphone, "777");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TESTHR(picRs-&gt;Update(&amp;rs));&nbsp;&nbsp; // Add change to the batch<BR>&nbsp;&nbsp;Rs1-&gt;MoveNext();<BR>}<BR>Rs1-&gt;Filter = (long) adFilterNone;<BR>......<BR>if (picRs) picRs-&gt;Release();<BR>Rs1-&gt;Close();<BR>pConn-&gt;Close();<BR>只要字段的状态是adFldOK，就可以访问。如果修改了字段，不要忘了先调用picRs的Update（注意不是Recordset的Update），然后才关闭，也不要忘了释放picRs（即picRs-&gt;Release();）。<BR>(4). 此时还可以用IADORecordBinding接口添加新纪录<BR>&nbsp;if(FAILED(picRs-&gt;AddNew(&amp;rs)))<BR>&nbsp;......<BR>11. 访问长数据<BR>在Microsoft SQL中的长数据包括text、image等这样长类型的数据，作为二进制字节来对待。<BR>可以用Field对象的GetChunk和AppendChunk方法来访问。每次可以读出或写入全部数据的一部分，它会记住上次访问的位置。但是如果中间访问了别的字段后，就又得从头来了。<BR>请看下面的例子：<BR>//写入一张照片到数据库：<BR>VARIANT varChunk;<BR>SAFEARRAY *psa;<BR>SAFEARRAYBOUND rgsabound[1];<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>//VT_ARRAY | VT_UI1<BR>CFile f("h:\\aaa.jpg",CFile::modeRead);<BR>BYTE&nbsp; bVal[ChunkSize+1];<BR>UINT uIsRead=0;<BR>//Create a safe array to store the array of BYTES&nbsp; <BR>while(1)<BR>{<BR>&nbsp;uIsRead=f.Read(bVal,ChunkSize);<BR>&nbsp;if(uIsRead==0)break;<BR>&nbsp;rgsabound[0].cElements =uIsRead;<BR>&nbsp;&nbsp;&nbsp; rgsabound[0].lLbound = 0;<BR>&nbsp;psa = SafeArrayCreate(VT_UI1,1,rgsabound);<BR>&nbsp;for(long index=0;index&lt;uIsRead;index++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;{<BR>&nbsp;&nbsp;if(FAILED(SafeArrayPutElement(psa,&amp;index,&amp;bVal[index])))<BR>&nbsp;&nbsp;::MessageBox(NULL,"啊，又出毛病了。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>&nbsp;varChunk.vt = VT_ARRAY|VT_UI1;<BR>&nbsp;varChunk.parray = psa;<BR>&nbsp;try{<BR>&nbsp;&nbsp;m_pRecordset-&gt;Fields-&gt;GetItem("photo")-&gt;AppendChunk(varChunk); <BR>&nbsp;}<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;CString str=(char*)e.Description();<BR>&nbsp;&nbsp;::MessageBox(NULL,str+"\n又出毛病了。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>&nbsp;::VariantClear(&amp;varChunk);<BR>&nbsp;::SafeArrayDestroyData( psa);<BR>&nbsp;if(uIsRead&lt;ChunkSize)break;<BR>}//while(1)&nbsp; <BR>f.Close();<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>//从数据库读一张照片：<BR>CFile f;<BR>f.Open("h:\\bbb.jpg",CFile::modeWrite|CFile::modeCreate);<BR>long lPhotoSize = m_pRecordset-&gt;Fields-&gt;Item["photo"]-&gt;ActualSize;&nbsp; <BR>long lIsRead=0;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>_variant_t varChunk;<BR>BYTE buf[ChunkSize];<BR>while(lPhotoSize&gt;0)<BR>{<BR>&nbsp;lIsRead=lPhotoSize&gt;=ChunkSize? ChunkSize:lPhotoSize;<BR>&nbsp;varChunk = m_pRecordset-&gt;Fields-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Item["photo"]-&gt;GetChunk(lIsRead);<BR>&nbsp;for(long index=0;index&lt;lIsRead;index++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;::SafeArrayGetElement(varChunk.parray,&amp;index,buf+index);&nbsp;&nbsp;&nbsp;<BR>&nbsp;}<BR>&nbsp;f.Write(buf,lIsRead);<BR>&nbsp;lPhotoSize-=lIsRead;<BR>}//while()<BR>f.Close();<BR>12. 使用SafeArray问题<BR>学会使用SafeArray也是很重要的，因为在ADO编程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在网络环境中，数组是不能直接传递的，而必须将其包装成SafeArray。实质上SafeArray就是将通常的数组增加一个描述符，说明其维数、长度、边界、元素类型等信息。SafeArray也并不单独使用，而是将其再包装到VARIANT类型的变量中，然后才作为参数传送出去。在VARIANT的vt成员的值如果包含VT_ARRAY|...,那么它所封装的就是一个SafeArray，它的parray成员即是指向SafeArray的指针。SafeArray中元素的类型可以是VARIANT能封装的任何类型，包括VARIANT类型本身。&nbsp;<BR>使用SafeArray的具体步骤：<BR>方法一：<BR>&nbsp;包装一个SafeArray：<BR>(1). 定义变量，如：<BR>&nbsp;VARIANT varChunk;<BR>&nbsp;SAFEARRAY *psa;<BR>&nbsp;&nbsp;&nbsp; SAFEARRAYBOUND rgsabound[1];<BR>(2). 创建SafeArray描述符：<BR>&nbsp;uIsRead=f.Read(bVal,ChunkSize);//read array from a file.<BR>&nbsp;if(uIsRead==0)break;<BR>&nbsp;rgsabound[0].cElements =uIsRead;<BR>&nbsp;rgsabound[0].lLbound = 0;<BR>&nbsp;psa = SafeArrayCreate(VT_UI1,1,rgsabound);<BR>(3). 放置数据元素到SafeArray：<BR>&nbsp;for(long index=0;index&lt;uIsRead;index++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;{<BR>&nbsp;&nbsp;if(FAILED(SafeArrayPutElement(psa,&amp;index,&amp;bVal[index])))<BR>&nbsp;&nbsp;&nbsp;::MessageBox(NULL,"出毛病了。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;}<BR>&nbsp;一个一个地放，挺麻烦的。<BR>(4). 封装到VARIANT内：<BR>&nbsp;varChunk.vt = VT_ARRAY|VT_UI1;<BR>&nbsp;varChunk.parray = psa;<BR>&nbsp;这样就可以将varChunk作为参数传送出去了。<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;读取SafeArray中的数据的步骤：<BR>(1). 用SafeArrayGetElement一个一个地读<BR>&nbsp;BYTE buf[lIsRead];<BR>&nbsp;for(long index=0;index&lt;lIsRead;index++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;::SafeArrayGetElement(varChunk.parray,&amp;index,buf+index);&nbsp;&nbsp;&nbsp;<BR>&nbsp;}<BR>&nbsp;就读到缓冲区buf里了。<BR>方法二：<BR>&nbsp;使用SafeArrayAccessData直接读写SafeArray的缓冲区：<BR>(1). 读缓冲区：<BR>&nbsp;BYTE *buf;<BR>&nbsp;SafeArrayAccessData(varChunk.parray, (void **)&amp;buf);<BR>&nbsp;f.Write(buf,lIsRead);<BR>&nbsp;SafeArrayUnaccessData(varChunk.parray);<BR>(2). 写缓冲区：<BR>&nbsp;BYTE *buf;<BR>&nbsp;::SafeArrayAccessData(psa, (void **)&amp;buf);<BR>&nbsp;for(long index=0;index&lt;uIsRead;index++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;{<BR>&nbsp;&nbsp;buf[index]=bVal[index];&nbsp;&nbsp;<BR>&nbsp;}<BR>&nbsp;::SafeArrayUnaccessData(psa);<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>&nbsp;varChunk.vt = VT_ARRAY|VT_UI1;<BR>&nbsp;varChunk.parray = psa;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>这种方法读写SafeArray都可以，它直接操纵SafeArray的数据缓冲区，比用SafeArrayGetElement和SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData(psa)，否则会出错的。<BR>13. 使用书签( bookmark )<BR>书签可以唯一标识记录集中的一个记录，用于快速地将当前记录移回到已访问过的记录，以及进行过滤等等。Provider会自动为记录集中的每一条记录产生一个书签，我们只需要使用它就行了。我们不能试图显示、修改或比较书签。ADO用记录集的Bookmark属性表示当前记录的书签。<BR>用法步骤：<BR>(1). 建立一个VARIANT类型的变量<BR>_variant_t VarBookmark;<BR>(2). 将当前记录的书签值存入该变量<BR>也就是记录集的Bookmark属性的当前值。<BR>&nbsp;VarBookmark = rst-&gt;Bookmark;<BR>(3). 返回到先前的记录<BR>将保存的书签值设置到记录集的书签属性中：<BR>&nbsp;// Check for whether bookmark set for a record<BR>&nbsp;if (VarBookmark.vt == VT_EMPTY)<BR>&nbsp;&nbsp;printf("No Bookmark set!\n");<BR>&nbsp;else <BR>&nbsp;&nbsp;rst-&gt;Bookmark = VarBookmark;<BR>设置完后，当前记录即会移动到该书签指向的记录。<BR>14、设置过滤条件<BR>Recordset对象的Filter属性表示了当前的过滤条件。它的值可以是以AND或OR连接起来的条件表达式（不含WHERE关键字）、由书签组成的数组或ADO提供的FilterGroupEnum枚举值。为Filter属性设置新值后Recordset的当前记录指针会自动移动到满足过滤条件的第一个记录。例如：<BR>rst-&gt;Filter&nbsp; = _bstr_t ("姓名='赵薇'&nbsp; AND&nbsp; 性别=’女’");<BR>在使用条件表达式时应注意下列问题：<BR>（1）、可以用圆括号组成复杂的表达式<BR>例如：<BR>rst-&gt;Filter&nbsp; =&nbsp; _bstr_t ("(姓名='赵薇'&nbsp; AND&nbsp; 性别=’女’)&nbsp; OR&nbsp; AGE&lt;25");<BR>但是微软不允许在括号内用OR，然后在括号外用AND，例如：<BR>rst-&gt;Filter&nbsp; = _bstr_t ("(姓名='赵薇'&nbsp; OR 性别=’女’)&nbsp; AND&nbsp; AGE&lt;25");<BR>必须修改为：<BR>rst-&gt;Filter&nbsp; = _bstr_t ("(姓名='赵薇'&nbsp; AND&nbsp; AGE&lt;25)&nbsp; OR&nbsp; (性别=’女’&nbsp; AND&nbsp; AGE&lt;25)");<BR>（2）、表达式中的比较运算符可以是LIKE<BR>LIKE后被比较的是一个含有通配符*的字符串，星号表示若干个任意的字符。<BR>字符串的首部和尾部可以同时带星号*<BR>rst-&gt;Filter&nbsp; =&nbsp; _bstr_t ("姓名 LIKE '*赵*' ");<BR>也可以只是尾部带星号：<BR>rst-&gt;Filter&nbsp; =&nbsp; _bstr_t ("姓名 LIKE '赵*' ");<BR>Filter属性值的类型是Variant，如果过滤条件是由书签组成的数组，则需将该数组转换为SafeArray，然后再封装到一个VARIANT或_variant_t型的变量中，再赋给Filter属性。<BR>15、索引与排序<BR>（1）、建立索引<BR>当以某个字段为关键字用Find方法查找时，为了加快速度可以以该字段为关键字在记录集内部临时建立索引。只要将该字段的Optimize属性设置为true即可，例如：<BR>pRst-&gt;Fields-&gt;GetItem("姓名")-&gt;Properties-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetItem("Optimize")-&gt;PutValue("True");<BR>pRst-&gt;Find("姓名 = '赵薇'",1,adSearchForward);<BR>......<BR>pRst-&gt;Fields-&gt;GetItem("姓名")-&gt;Properties-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetItem("Optimize")-&gt;PutValue("False");<BR>pRst-&gt;Close();<BR>说明：Optimize属性是由Provider提供的属性（在ADO中称为动态属性），ADO本身没有此属性。<BR>（2）、排序<BR>要排序也很简单，只要把要排序的关键字列表设置到Recordset对象的Sort属性里即可，例如：<BR>pRstAuthors-&gt;CursorLocation = adUseClient;<BR>pRstAuthors-&gt;Open("SELECT * FROM mytable",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _variant_t((IDispatch *) pConnection),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adOpenStatic, adLockReadOnly, adCmdText);<BR>......<BR>pRst-&gt;Sort = "姓名 DESC, 年龄 ASC";<BR>关键字（即字段名）之间用逗号隔开，如果要以某关键字降序排序，则应在该关键字后加一空格，再加DESC（如上例）。升序时ASC加不加无所谓。本操作是利用索引进行的，并未进行物理排序，所以效率较高。<BR>但要注意，在打开记录集之前必须将记录集的CursorLocation属性设置为adUseClient，如上例所示。Sort属性值在需要时随时可以修改。<BR>16、事务处理<BR>ADO中的事务处理也很简单，只需分别在适当的位置调用Connection对象的三个方法即可，这三个方法是：<BR>（1）、在事务开始时调用<BR>pCnn-&gt;BeginTrans();<BR>（2）、在事务结束并成功时调用<BR>pCnn-&gt;CommitTrans ();<BR>（3）、在事务结束并失败时调用<BR>pCnn-&gt;RollbackTrans ();<BR>在使用事务处理时，应尽量减小事务的范围，即减小从事务开始到结束（提交或回滚）之间的时间间隔，以便提高系统效率。需要时也可在调用BeginTrans()方法之前，先设置Connection对象的IsolationLevel属性值，详细内容参见MSDN中有关ADO的技术资料。<BR>三、使用ADO编程常见问题解答<BR>以下均是针对MS SQL 7.0编程时所遇问题进行讨论。<BR>1、连接失败可能原因<BR>Enterprise Managemer内，打开将服务器的属性对话框，在Security选项卡中，有一个选项Authentication。<BR>如果该选项是Windows NT only，则你的程序所用的连接字符串就一定要包含Trusted_Connection参数，并且其值必须为yes，如：<BR>"Provider=SQLOLEDB;Server=888;Trusted_Connection=yes"<BR>&nbsp;&nbsp;";Database=master;uid=lad;";<BR>如果不按上述操作，程序运行时连接必然失败。<BR>如果Authentication选项是SQL Server and Windows NT，则你的程序所用的连接字符串可以不包含Trusted_Connection参数，如：<BR>"Provider=SQLOLEDB;Server=888;Database=master;uid=lad;pwd=111;";<BR>因为ADO给该参数取的默认值就是no，所以可以省略。我认为还是取默认值比较安全一些。<BR>2、改变当前数据库的方法<BR>使用Tansct-SQL中的USE语句即可。<BR>3、如何判断一个数据库是否存在<BR>(1)、可打开master数据库中一个叫做SCHEMATA的视图，其内容列出了该服务器上所有的数据库名称。<BR>(2) 、更简便的方法是使用USE语句，成功了就存在；不成功，就不存在。例如：<BR>&nbsp;try{<BR>&nbsp;&nbsp;m_pConnect-&gt;Execute ( _bstr_t("USE INSURANCE_2002"),NULL,<BR>&nbsp;&nbsp;adCmdText|adExecuteNoRecords );<BR>&nbsp;}<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;blSuccess=FALSE;<BR>&nbsp;&nbsp;CString str="数据库INSURANCE_2002不存在！\n";<BR>&nbsp;&nbsp;str+=e.Description();<BR>&nbsp;&nbsp;::MessageBox(NULL,str,"警告",MB_OK | MB_ICONWARNING);&nbsp;<BR>&nbsp;}<BR>4、判断一个表是否存在<BR>（1）、同样判断一个表是否存在，也可以用是否成功地打开它来判断，十分方便，例如：<BR>&nbsp;try{<BR>&nbsp;&nbsp;m_pRecordset-&gt;Open(_variant_t("mytable"),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _variant_t((IDispatch *)m_pConnection,true), adOpenKeyset,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adLockOptimistic, adCmdTable);<BR>&nbsp;}<BR>&nbsp;catch (_com_error &amp;e)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBox(NULL,"该表不存在。","提示",MB_OK | MB_ICONWARNING);<BR>&nbsp;}</P>
<P>(2)、要不然可以采用麻烦一点的办法，就是在MS-SQL服务器上的每个数据库中都有一个名为sysobjects的表，查看此表的内容即知指定的表是否在该数据库中。<BR>(3)、同样，每个数据库中都有一个名为TABLES的视图(View)，查看此视图的内容即知指定的表是否在该数据库中。<BR>5、类型转换问题<BR>（1）、类型VARIANT_BOOL<BR>类型VARIANT_BOOL等价于short类型。The VARIANT_BOOL is equivalent to short. see it's definition below: <BR>typdef short VARIANT_BOOL<BR>（2）、_com_ptr_t类的类型转换<BR>_ConnectionPtr可以自动转换成IDspatch*类型，这是因为_ConnectionPtr实际上是_com_ptr_t类的一个实例，而这个类有此类型转换函数。<BR>同理，_RecordsetPtr和_CommandPtr也都可以这样转换。<BR>（3）、_bstr_t和_variant_t类<BR>在ADO编程时，_bstr_t和_variant_t这两个类很有用，省去了许多BSTR和VARIANT类型转换的麻烦。<BR>6、打开记录集时的问题<BR>在打开记录集时，在调用Recordset的Open方法时，其最后一个参数里一定不能包含adAsyncExecute，否则将因为是异步操作，在读取数据时无法读到数据。<BR>7、异常处理问题<BR>对所有调用ADO的语句一定要用try和catch语句捕捉异常，否则在发生异常时，程序会异常退出。<BR>8、使用SafeArray问题<BR>在初学使用中，我曾遇到一个伤脑筋的问题，一定要注意：<BR>在定义了SAFEARRAY的指针后，如果打算重复使用多次，则在中间可以调用::SafeArrayDestroyData释放数据，但决不能调用::SafeArrayDestroyDescriptor，否则必然出错，即使调用SafeArrayCreate也不行。例如：<BR>SAFEARRAY *psa;<BR>......<BR>//When the data are no longer to be used:<BR>::SafeArrayDestroyData( psa);<BR>我分析在定义psa指针时，一个SAFEARRAY的实例（也就是SAFEARRAY描述符）也同时被自动建立了。但是只要一调用::SafeArrayDestroyDescriptor，描述符就被销毁了。<BR>所以我认为::SafeArrayDestroyDescriptor可以根本就不调用，即使调用也必须在最后调用。<BR>9、重复使用命令对象问题<BR>一个命令对象如果要重复使用多次（尤其是带参数的命令），则在第一次执行之前，应将它的Prepared属性设置为TRUE。这样会使第一次执行减慢，但却可以使以后的执行全部加快。<BR>10、绑定字符串型字段问题<BR>如果要绑定的字段是字符串类型，则对应的字符数组的元素个数一定要比字段长度大2（比如m_szau_fname[22]，其绑定的字段au_fname的长度实际是20），不这样绑定就会失败。<BR>11、使用AppendChunk的问题<BR>当用AddNew方法刚刚向记录集内添加一个新记录之后，不能首先向一个长数据字段（image类型）写入数据，必须先向其他字段写入过数据之后，才能调用AppendChunk写该字段，否则出错。也就是说，AppendChunk不能紧接在AddNew之后。另外，写入其他字段后还必须紧接着调用AppendChunk，而不能调用记录集的Update方法后，才调用AppendChunk，否则调用AppendChunk时也会出错。换句话说，就是必须AppendChunk在前，Update在后。因而这个时候就不能使用带参数的AddNew了，因为带参数的AddNew会自动调用记录集的Update，所以AppendChunk就跑到Update的后面了，就只有出错了！因此，这时应该用不带参数的AddNew。<BR>我推测这可能是MS SQL 7.0的问题，在MS SQL 2000中则不存在这些问题，但是AppendChunk仍然不能在Update之后。<BR>四、小结<BR>一般情况下，Connection和Command的Execute用于执行不产生记录集的命令，而Recordset的Open用于产生一个记录集，当然也不是绝对的。特别Command主要是用于执行参数化的命令，可以直接由Command对象执行，也可以将Command对象传递给Recordset的Open。<BR>本文中的代码片断均在VC++ 6.0、Windows NT 4.0 SP6和MS SQL 7.0中调试通过。相信您读过之后，编写简单的数据库程序应该没有问题了。当然要编写比较实用的、复杂一点的程序，还需要对OLE DB、ADO以及数据库平台再多了解一点，希望您继续努力，一定会很快成功的！详细参考资料请参见微软MSDN July 2000光盘或MS SQL 7.0在线文档资料（Books online）。文中难免有错误和不妥之处，敬请各位批评指正！<FONT color=#ffffcc>www.chinai tp 采吧采吧不是罪 ow er.comJuJIe</FONT></P>
<P>参考文献：<BR>1、 微软MSDN Library - July 2000 / Platform SDK / Data Services / Microsoft Data Access Components (MDAC) / Microsoft ActiveX Data Objects (ADO)<BR>2、 微软MS SQL 7.0在线文档资料（Books online）---- Building SQL Server Applications / ADO and SQL Server<BR>3、 微软MS SQL 7.0在线文档资料（Books online）---- Building SQL Server Applications / Transact – SQL Reference<BR>4、 微软MSDN Library - July 2000 / Platform SDK / Data Services / Microsoft Data Access Components (MDAC) / Microsoft OLE DB</P><img src ="http://www.cppblog.com/ivenher/aggbug/1773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-12-15 11:03 <a href="http://www.cppblog.com/ivenher/articles/1773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC数据库编程中的打印控制</title><link>http://www.cppblog.com/ivenher/articles/1079.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Fri, 11 Nov 2005 06:31:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/1079.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/1079.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/1079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/1079.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/1079.html</trackback:ping><description><![CDATA[<TABLE style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD style="FONT-SIZE: 22px" align=middle height=60>VC数据库编程中的打印控制</TD></TR>
<TR>
<TD style="FONT-SIZE: 9pt" align=middle height=30><FONT color=#00ff00>2003-12-4</FONT>加入&nbsp;&nbsp;来自<FONT color=#00ff00>赛迪网</FONT>&nbsp;&nbsp;作者<FONT color=#00ff00>李佑民</FONT>&nbsp;&nbsp;<FONT color=#00ff00>1</FONT>条评论&nbsp;&nbsp;点击<FONT color=#ff0000>2287</FONT>次</TD></TR>
<TR>
<TD style="FONT-SIZE: 14px" width="100%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>　　VC数据库编程中的打印控制比较复杂，但它也给程序员最大的灵活性，而这种灵活性正是我们需要的。因为各行业、部门的报表一般都不太规整，特别是表头部分，二、三重嵌套的情况很常见。下面我们就开发中碰到的一些问题与同行们探讨。&nbsp;<BR><BR>　　Document/View框架之外的打印&nbsp;<BR><BR>　　熟悉VC的程序员都知道Microsoft&nbsp;的AppWizard生成的应用程序框架中，可以选择免费的打印及打印预览功能，但前提是必须选择Document/View结构。然而我们的数据库应用中一般都不需要一个文档类来保存文档，因为数据库（源）就是我们的文档，数据一般是在一个对话框或视中与用户交互，编辑或修改结果直接通过数据库引擎写回数据库中。我们的程序主框架要么是基于对话框的、要么是基于无文档类的单视（或多视）结构，在这种情况下，AppWizard&nbsp;在打印控制部分并不能给我们任何帮助，只能自己负责完成打印控制。&nbsp;<BR><BR>　　总结起来，一次打印操作要遵循以下步骤：&nbsp;<BR><BR>　　1.得到或生成打印设备场景，可通过显示打印对话框让用户选择打印机与纸张等设置，也可在程序中直接取系统缺省打印机设置，然后根据报表格式设置纸张大小和打印方向；&nbsp;<BR><BR>　　2.开始在该设备场景中的一次打印作业，实际打印报表内容，终止打印作业；&nbsp;<BR><BR>　　3.清除打印设备场景，完成本次打印操作。&nbsp;<BR><BR>　　在下面的例子中，我们在一个对话框中让用户选择打印某个报表，没有显示打印设置对话框，而是直接取系统缺省打印机设置，然后根据报表格式设置纸张大小和打印方向。之所以这样做是因为各行业、部门的报表格式一般都是至上而下的统一格式。函数DoPreparePrintDC()、DoPrint()和DoClearPrintDC()分别对应上述的三个步骤：&nbsp;<BR><BR>　　BOOL&nbsp;CMyDialog::DoPreparePrintDC()&nbsp;<BR><BR>　　//&nbsp;准备打印场景&nbsp;<BR><BR>　　{&nbsp;<BR><BR>　　&nbsp;＃define　　FONTSIZE&nbsp;14&nbsp;<BR><BR>　　&nbsp;//&nbsp;获取打印机的设备属性&nbsp;<BR><BR>　　&nbsp;CPrintDialog&nbsp;dlgPrint(&nbsp;FALSE&nbsp;);&nbsp;<BR><BR>　　&nbsp;//&nbsp;得到当前系统缺省打印机设置&nbsp;<BR><BR>　　&nbsp;if(!dlgPrint.GetDefaults())&nbsp;return&nbsp;FALSE;&nbsp;<BR><BR>　　&nbsp;LPDEVMODE&nbsp;pDM=dlgPrint.GetDevMode();&nbsp;<BR><BR>　　&nbsp;if(pDM==NULL)&nbsp;return&nbsp;FALSE;&nbsp;<BR><BR>　　&nbsp;::GlobalUnlock(pDM);&nbsp;<BR><BR>　　&nbsp;//&nbsp;联结打印DC，m—hDC是定义为HDC&nbsp;m—hDC的类成员变量&nbsp;<BR><BR>　　&nbsp;m—hDC=dlgPrint.CreatePrinterDC();&nbsp;<BR><BR>　　&nbsp;//&nbsp;m—DC是定义为CDC&nbsp;m—DC的类成员变量&nbsp;<BR><BR>　　&nbsp;if(!m—DC.Attach(m—hDC)&nbsp;return&nbsp;FALSE;&nbsp;<BR><BR>　　&nbsp;//&nbsp;设置打印标志&nbsp;<BR><BR>　　&nbsp;m—DC.m—bPrinting=TRUE;&nbsp;<BR><BR>　　&nbsp;short&nbsp;cxInch=m—DC.GetDeviceCaps(LOGPIXELSX);&nbsp;<BR><BR>　　&nbsp;short&nbsp;cyInch=m—DC.GetDeviceCaps(LOGPIXELSY);&nbsp;<BR><BR>　　&nbsp;//&nbsp;建立打印字体，m—fontPrint&nbsp;是定义为CFont&nbsp;m_fontPrint的类成员变量&nbsp;<BR><BR>　　&nbsp;if(!m—fontPrint.CreateFont(MulDiv(FONTSIZE,&nbsp;－cyInch,&nbsp;72),0,0,0,&nbsp;FW—NORMAL,0,0,0,&nbsp;GB2312—CHARSET,&nbsp;OUT—CHARACTER—PRECIS,&nbsp;CLIP—CHARACTER—PRECIS,DEFAULT—QUALITY,&nbsp;DEFAULT—PITCH|FF—DONTCARE,&nbsp;HFONTNAME)&nbsp;<BR><BR>　　&nbsp;return&nbsp;FALSE;&nbsp;<BR><BR>　　&nbsp;return&nbsp;TRUE;}&nbsp;<BR><BR>　　void&nbsp;CDlgDataPrint::DoClearPrintDC()&nbsp;<BR><BR>　　//&nbsp;清除打印场景&nbsp;<BR><BR>　　{&nbsp;m—fontPrint.DeleteObject();&nbsp;<BR><BR>　　&nbsp;m—DC.Detach();&nbsp;<BR><BR>　　&nbsp;::DeleteDC(&nbsp;m—hDC&nbsp;);}&nbsp;<BR><BR>　　void&nbsp;CDlgDataPrint::DoPrint()&nbsp;<BR><BR>　　//&nbsp;实际打印输出&nbsp;<BR><BR>　　{&nbsp;if(DoPreparePrintDC()==FALSE)&nbsp;return;&nbsp;<BR><BR>　　&nbsp;//&nbsp;开始一次打印作业&nbsp;<BR><BR>　　&nbsp;CString&nbsp;str;&nbsp;<BR><BR>　　&nbsp;str.LoadString(AFX—IDS—APP—TITLE);&nbsp;<BR><BR>　　&nbsp;DOCINFO&nbsp;di;&nbsp;<BR><BR>　　&nbsp;::ZeroMemory&nbsp;(＆di,&nbsp;sizeof&nbsp;(DOCINFO));&nbsp;<BR><BR>　　&nbsp;di.cbSize=sizeof&nbsp;(DOCINFO);&nbsp;<BR><BR>　　&nbsp;di.lpszDocName=str;&nbsp;<BR><BR>　　&nbsp;m—DC.StartDoc(＆di);&nbsp;<BR><BR>　　&nbsp;m—DC.StartPage();&nbsp;<BR><BR>　　&nbsp;//&nbsp;将打印字体选进设备场景&nbsp;<BR><BR>　　&nbsp;CFont＊&nbsp;pOldFont=m—DC.SelectObject(＆m—fontPrint);&nbsp;<BR><BR>　　&nbsp;//&nbsp;输出报表，建议用CDC::DrawText()函数便于控制打印范围&nbsp;<BR><BR>　　&nbsp;...&nbsp;<BR><BR>　　&nbsp;//&nbsp;终止打印作业&nbsp;<BR><BR>　　&nbsp;m—DC.EndPage();&nbsp;<BR><BR>　　&nbsp;m—DC.EndDoc();&nbsp;<BR><BR>　　&nbsp;m—DC.SelectObject(pOldFont);&nbsp;<BR><BR>　　&nbsp;//&nbsp;清除打印场景&nbsp;<BR><BR>　　&nbsp;DoClearPrintDC();}&nbsp;<BR><BR>　　表格问题&nbsp;<BR><BR>　　对格式固定或表头、表体比较复杂的情况，特别是有嵌套表格的情况下，我们认为先将打印结果以文本形式写入一临时文件，然后再对文件进行打印输出的方法会使事情简单一些。因为这样在程序中就可以只关心数据(表体)的输出，而表头则可以固定格式存入数据库。&nbsp;<BR><BR>　　但是，我们在对文本形式的报表进行打印输出时却发现一个有趣的现象，有时输出结果的相邻两行表格竖线不能对齐，而有时又可以。原来是&nbsp;Windows&nbsp;图形输出的问题，只要我们在建立打印字体时，字体的高度是偶数就可保证竖线对齐，如果是奇数则不能对齐。知道了原因，在建立打印字体时只需加入如下代码即可：&nbsp;<BR><BR>　　...&nbsp;<BR><BR>　　＃define　　FONTSIZE&nbsp;14&nbsp;<BR><BR>　　＃define　　HFONTNAME&nbsp;″宋体″&nbsp;<BR><BR>　　//&nbsp;建立打印字体，m—fontPrint是定义为CFont&nbsp;m—fontPrint的类成员变量&nbsp;<BR><BR>　　int&nbsp;nFontHeight=MulDiv(FONTSIZE,－cyInch,&nbsp;72);&nbsp;<BR><BR>　　if(nFontHeight&nbsp;％&nbsp;2)&nbsp;nFontHeight＋＋;&nbsp;<BR><BR>　　if(!m—fontPrint.CreateFont(nFontHeight,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;FW—NORMAL,&nbsp;0,&nbsp;0,0,GB2312—CHARSET,&nbsp;OUT—CHARACTER—PRECIS,&nbsp;CLIP—CHARACTER—PRECIS,DEFAULT—QUALITY,&nbsp;DEFAULT—PITCH&nbsp;|&nbsp;FF—DONTCARE,&nbsp;HFONTNAME))&nbsp;<BR><BR>　　&nbsp;return&nbsp;FALSE;&nbsp;<BR><BR>　　...&nbsp;<BR><BR>　　还有一点小技巧，输出文本形式的报表时，对报表的横线只需要输出其正常高度的二分之一或三分之一，这样报表看起来更紧凑美观。这也是我们在前面建议用CDC::DrawText()进行绘制输出的原因。&nbsp;<BR></TD></TR></TBODY></TABLE><img src ="http://www.cppblog.com/ivenher/aggbug/1079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-11-11 14:31 <a href="http://www.cppblog.com/ivenher/articles/1079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ADO开发中如何得到表格字段名</title><link>http://www.cppblog.com/ivenher/articles/1055.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Fri, 11 Nov 2005 03:09:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/1055.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/1055.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/1055.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/1055.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/1055.html</trackback:ping><description><![CDATA[<BR>1. 代码说明 <BR>(1)在 stdafx.h 加入如下代码引入 ADO 库定义<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>，<PRE>#import "c:\program files\common files\system\ado\msado15.dll" 			no_namespace 		rename ("EOF", "adoEOF")
</PRE>(2)初始化COM库，在BOOL CGetFieldNameApp::InitInstance()中添加AfxOleInit(); 
<P></P><BR>(3)在类 CgetFieldNameDlg 中添加两个用于打开<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>连接和打开记录集的变量；<PRE>_ConnectionPtr m_pConnection;
	_RecordsetPtr m_pRecordset;
</PRE>(4) 在CgetFieldNameDlg的构造函数中添加<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>连接和记录集初始化代码；<PRE>m_pConnection.CreateInstance(__uuidof(Connection));
try                 
{	
	m_pConnection-&gt;Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\FTI.mdb",
			"",
			"",
			adModeUnknown
			);
}
catch(_com_error e)
{
	AfxMessageBox("<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>连接失败!");
} 
m_pRecordset.CreateInstance(__uuidof(Recordset));</PRE>(5) 给Listbox控件添加控件变量m_FieldsList；<BR>(6) 在按钮的单击事件中添加相应代码；<PRE>_bstr_t   mStrSQL;
CString   strColName;
BSTR      bstrColName;
long      ColCount,i; 
Field *   field = NULL;		
HRESULT   hr;
Fields *  fields = NULL;
LPCTSTR   nameField;
	
//打开记录集，得到字段名，并将字段名信息添加到ListBox中

mStrSQL = "SELECT * FROM Images";

m_pRecordset-&gt;Open(mStrSQL,               
		m_pConnection.GetInterfacePtr(),	 
		adOpenDynamic,
		adLockOptimistic,
		adCmdText);
	
hr = m_pRecordset-&gt;get_Fields (&amp;fields);	//得到记录集的字段集和	
	 
if(SUCCEEDED(hr)) 
    fields-&gt;get_Count(&amp;ColCount);	

//得到记录集的字段集合中的字段的总个数	

for(i=0;i&lt;ColCount;i++)			
{			
	fields-&gt;Item[i]-&gt;get_Name(&amp;bstrColName);	//得到记录集//中的字段名
	strColName=bstrColName;	
	nameField = strColName;
	m_FieldsList.AddString(nameField);
}		

if(SUCCEEDED(hr))
	fields-&gt;Release();//释放指针
</PRE><img src ="http://www.cppblog.com/ivenher/aggbug/1055.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-11-11 11:09 <a href="http://www.cppblog.com/ivenher/articles/1055.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用udl建立到sybase的连接</title><link>http://www.cppblog.com/ivenher/articles/1012.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Wed, 09 Nov 2005 08:25:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/1012.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/1012.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/1012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/1012.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/1012.html</trackback:ping><description><![CDATA[<P>新建一个udl文件。选择提供程序。如下图<BR><IMG height=437 alt=选择提供程序.JPG src="http://www.cppblog.com/images/cppblog_com/ivenher/选择提供程序.JPG" width=419 border=0><BR><BR>选择下一步。<BR><IMG height=437 alt=第二步.JPG src="http://www.cppblog.com/images/cppblog_com/ivenher/第二步.JPG" width=419 border=0><BR><BR>数据源为利用 sybase ase ole Configuration Manager所建立的数据源。</P><img src ="http://www.cppblog.com/ivenher/aggbug/1012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-11-09 16:25 <a href="http://www.cppblog.com/ivenher/articles/1012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Connection大全</title><link>http://www.cppblog.com/ivenher/articles/1008.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Wed, 09 Nov 2005 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/1008.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/1008.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/1008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/1008.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/1008.html</trackback:ping><description><![CDATA[<BR>1.Sqlserver <BR>&nbsp;&nbsp;A.ODBC <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;Security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={SQL&nbsp;Server};Server=Aron1;Database=pubs;Uid=sa;Pwd=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Trusted&nbsp;connection: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={SQL&nbsp;Server};Server=Aron1;Database=pubs; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trusted_Connection=yes;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;III.Prompt&nbsp;for&nbsp;username&nbsp;and&nbsp;password: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oConn.Properties("Prompt")&nbsp;=&nbsp;adPromptAlways <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oConn.Open&nbsp;"Driver={SQL&nbsp;Server};Server=Aron1;DataBase=pubs;"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;Security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=sqloledb;Data&nbsp;Source=Aron1;Initial&nbsp;Catalog=pubs;User&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id=sa;Password=asdasd;" <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Trusted&nbsp;Connection: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=sqloledb;Data&nbsp;Source=Aron1;Initial&nbsp;Catalog=pubs; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integrated&nbsp;Security=SSPI;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(仅适用于Sqlserver&nbsp;2000) <BR>&nbsp;&nbsp;&nbsp;&nbsp;III.Prompt&nbsp;for&nbsp;username&nbsp;and&nbsp;password: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oConn.Provider&nbsp;=&nbsp;"sqloledb" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oConn.Properties("Prompt")&nbsp;=&nbsp;adPromptAlways <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oConn.Open&nbsp;"Data&nbsp;Source=Aron1;Initial&nbsp;Catalog=pubs;"&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;IV.Connect&nbsp;via&nbsp;an&nbsp;IP&nbsp;address: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=sqloledb;Data&nbsp;Source=190.190.200.100,1433;Network <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Library=DBMSSOCN;Initial&nbsp;Catalog=pubs;User&nbsp;ID=sa;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;C.SqlConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;Security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Data&nbsp;Source=Aron1;Initial&nbsp;Catalog=pubs;User&nbsp;Id=sa;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或者"Server=Aron1;Database=pubs;User&nbsp;ID=sa;Password=asdasd; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trusted_Connection=False"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Trusted&nbsp;Connection: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Data&nbsp;Source=Aron1;Initial&nbsp;Catalog=pubs;Integrated&nbsp;Security=SSPI;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或者"Server=Aron1;Database=pubs;Trusted_Connection=True;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(仅适用于Sqlserver&nbsp;2000) <BR>&nbsp;&nbsp;&nbsp;&nbsp;III.Connect&nbsp;via&nbsp;an&nbsp;IP&nbsp;address: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Data&nbsp;Source=190.190.200.100,1433;Network&nbsp;Library=DBMSSOCN;Initial&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Catalog=pubs;User&nbsp;ID=sa;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Network&nbsp;library&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbnmpntw&nbsp;&nbsp;&nbsp;Win32&nbsp;Named&nbsp;Pipes&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbmssocn&nbsp;&nbsp;&nbsp;Win32&nbsp;Winsock&nbsp;TCP/IP&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbmsspxn&nbsp;&nbsp;&nbsp;Win32&nbsp;SPX/IPX&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbmsvinn&nbsp;&nbsp;&nbsp;Win32&nbsp;Banyan&nbsp;Vines&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbmsrpcn&nbsp;&nbsp;&nbsp;Win32&nbsp;Multi-Protocol&nbsp;(Windows&nbsp;RPC)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过SQLOLEDB&nbsp;provider&nbsp;连接，用Network&nbsp;Library=dbmssocn，通过MSDASQL <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;provider连接，用Network=dbmssocn&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;IV.声明方法： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C#: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;System.Data.SqlClient; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlConnection&nbsp;oSQLConn&nbsp;=&nbsp;new&nbsp;SqlConnection(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oSQLConn.ConnectionString="my&nbsp;connectionstring"; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oSQLConn.Open();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VB.NET: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Imports&nbsp;System.Data.SqlClient <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;oSQLConn&nbsp;As&nbsp;SqlConnection&nbsp;=&nbsp;New&nbsp;SqlConnection() <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oSQLConn.ConnectionString="my&nbsp;connectionstring" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oSQLConn.Open()&nbsp; <BR>&nbsp;&nbsp;D.Data&nbsp;Shape&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;MS&nbsp;Data&nbsp;Shape <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Provider=MSDataShape;Data&nbsp;Provider=SQLOLEDB;Data&nbsp;Source=Aron1;Initial <BR>&nbsp;&nbsp;&nbsp;&nbsp;Catalog=pubs;User&nbsp;ID=sa;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;呵呵，Data&nbsp;Shape没用过，请参照 <BR>&nbsp;&nbsp;&nbsp;&nbsp;http://www.4guysfromrolla.com/webtech/092599-1.shtml <BR>2.Access&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;Security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Access&nbsp;Driver&nbsp;(*.mdb)};Dbq=C:\mydatabase.mdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Uid=Admin;Pwd=;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Workgroup: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Access&nbsp;Driver&nbsp;(*.mdb)};Dbq=C:\mydatabase.mdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SystemDB=C:\mydatabase.mdw;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;III.Exclusive: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Access&nbsp;Driver&nbsp;(*.mdb)};Dbq=C:\mydatabase.mdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exclusive=1;Uid=admin;Pwd=" <BR>&nbsp;&nbsp;B.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=\somepath\mydb.mdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;Id=admin;Password=;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Workgroup&nbsp;(system&nbsp;database): <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=\somepath\mydb.mdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Jet&nbsp;OLEDB:System&nbsp;Database=system.mdw;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;III.With&nbsp;password: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=\somepath\mydb.mdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Jet&nbsp;OLEDB:Database&nbsp;Password=MyDbPassword;"&nbsp; <BR>3.Oracle&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.New&nbsp;version: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;ODBC&nbsp;for&nbsp;Oracle};Server=OracleServer.world; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Uid=Username;Pwd=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Old&nbsp;version: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;ODBC&nbsp;Driver&nbsp;for&nbsp;Oracle};ConnectString= <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OracleServer.world;Uid=myUsername;Pwd=myPassword;"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=msdaora;Data&nbsp;Source=MyOracleDB;User&nbsp;Id=UserName; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注：上面是用MS的驱动，下面是用Oracle提供的驱动： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=OraOLEDB.Oracle;Data&nbsp;Source=MyOracleDB;User <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id=Username;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Trusted&nbsp;Connection: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=OraOLEDB.Oracle;Data&nbsp;Source=MyOracleDB;OSAuthent=1;"&nbsp; <BR>&nbsp;&nbsp;C.OracleConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Data&nbsp;Source=Oracle8i;Integrated&nbsp;Security=yes";&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注：此写法用于Oracle&nbsp;8i&nbsp;release&nbsp;3及以上版本。 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;声明方法: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C#: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;System.Data.OracleClient; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OracleConnection&nbsp;oOracleConn&nbsp;=&nbsp;new&nbsp;OracleConnection(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oOracleConn.ConnectionString&nbsp;=&nbsp;"my&nbsp;connectionstring"; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oOracleConn.Open();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VB.NET: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Imports&nbsp;System.Data.OracleClient <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;oOracleConn&nbsp;As&nbsp;OracleConnection&nbsp;=&nbsp;New&nbsp;OracleConnection() <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oOracleConn.ConnectionString&nbsp;=&nbsp;"my&nbsp;connectionstring" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oOracleConn.Open()&nbsp; <BR>&nbsp;&nbsp;D.Data&nbsp;Shape&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.MS&nbsp;Data&nbsp;Shape: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=MSDataShape.1;Persist&nbsp;Security&nbsp;Info=False;Data&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Provider=MSDAORA;Data&nbsp;Source=orac;user&nbsp;id=username;password=mypw" <BR>3.MySQL&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Local&nbsp;database: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={mySQL};Server=mySrvName;Option=16834;Database=mydatabase;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Remote&nbsp;database: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={mySQL};Server=data.domain.com;Port=3306;Option=131072; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stmt=;Database=my-database;Uid=username;Pwd=password;"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=MySQLProv;Data&nbsp;Source=mydb;User&nbsp;Id=UserName; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Password=asdasd;"&nbsp; <BR>&nbsp;&nbsp;C.MySqlConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.eInfoDesigns.dbProvider: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Data&nbsp;Source=server;Database=mydb;User&nbsp;ID=username; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Password=pwd;Command&nbsp;Logging=false"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注：此写法仅用于通过eInfoDesigns&nbsp;dbProvider连接： <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.声明方法： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C#: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;eInfoDesigns.dbProvider.MySqlClient; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MySqlConnection&nbsp;oMySqlConn&nbsp;=&nbsp;new&nbsp;MySqlConnection(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oMySqlConn.ConnectionString&nbsp;=&nbsp;"my&nbsp;connectionstring"; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oMySqlConn.Open();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VB.NET: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Imports&nbsp;eInfoDesigns.dbProvider.MySqlClient <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;oMySqlConn&nbsp;As&nbsp;MySqlConnection&nbsp;=&nbsp;New&nbsp;MySqlConnection() <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oMySqlConn.ConnectionString&nbsp;=&nbsp;"my&nbsp;connectionstring" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oMySqlConn.Open()&nbsp;&nbsp;&nbsp; <BR>4.Interbase&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp;(Easysoft&nbsp;ODBC-Interbase&nbsp;driver&nbsp;)&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Local&nbsp;computer: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Easysoft&nbsp;IB6&nbsp;ODBC};Server=localhost;Database=localhost: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C:\mydatabase.gdb;Uid=username;Pwd=password"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.Remote&nbsp;Computer: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Easysoft&nbsp;IB6&nbsp;ODBC};Server=ComputerName;Database=ComputerName <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:C:\mydatabase.gdb;Uid=username;Pwd=password"&nbsp; <BR>&nbsp;&nbsp;B.ODBC&nbsp;(Intersolv&nbsp;ODBC-Interbase&nbsp;driver&nbsp;) <BR>&nbsp;&nbsp;&nbsp;I.Local&nbsp;computer: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={INTERSOLV&nbsp;InterBase&nbsp;ODBC&nbsp;Driver&nbsp;(*.gdb)};Server=localhost; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Database=localhost:C:\mydatabase.gdb;Uid=username;Pwd=password"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.Remote&nbsp;Computer: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={INTERSOLV&nbsp;InterBase&nbsp;ODBC&nbsp;Driver&nbsp;(*.gdb)}; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Server=ComputerName;Database=ComputerName:C:\mydatabase.gdb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Uid=username;Pwd=password"&nbsp; <BR>&nbsp;&nbsp;C.OLE&nbsp;DB&nbsp;(SIBPROvider&nbsp;Driver)&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"provider=sibprovider;location=localhost:;data&nbsp;source=c: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\databases\gdbs\mygdb.gdb;user&nbsp;id=SYSDBA;password=masterkey"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.Specifying&nbsp;character&nbsp;set: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"provider=sibprovider;location=localhost:;data&nbsp;source=c: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\databases\gdbs\mygdb.gdb;user&nbsp;id=SYSDBA;password=masterkey; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;character&nbsp;set=ISO8859_1"&nbsp; <BR>&nbsp;&nbsp;&nbsp;III.Specifying&nbsp;role: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"provider=sibprovider;location=localhost:;data&nbsp;source=c: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\databases\gdbs\mygdb.gdb;user&nbsp;id=SYSDBA;password=masterkey; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;role=DIGITADORES" <BR>6.IBM&nbsp;DB2&nbsp; <BR>&nbsp;&nbsp;A.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp;from&nbsp;ms&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.TCP/IP: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=DB2OLEDB;Network&nbsp;Transport&nbsp;Library=TCPIP;Network&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Address=XXX.XXX.XXX.XXX;Initial&nbsp;Catalog=MyCtlg;Package&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collection=MyPkgCol;Default&nbsp;Schema=Schema;User&nbsp;ID=MyUser;Password=MyPW"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.APPC: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Provider=DB2OLEDB;APPC&nbsp;Local&nbsp;LU&nbsp;Alias=MyAlias;APPC&nbsp;Remote&nbsp;LU&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Alias=MyRemote;Initial&nbsp;Catalog=MyCtlg;Package&nbsp;Collection=MyPkgCol;Default&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Schema=Schema;User&nbsp;ID=MyUser;Password=MyPW"&nbsp;&nbsp; <BR>7.Sybase&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard&nbsp;Sybase&nbsp;System&nbsp;12&nbsp;(or&nbsp;12.5)&nbsp;Enterprise&nbsp;Open&nbsp;Client: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={SYBASE&nbsp;ASE&nbsp;ODBC&nbsp;Driver};Srvr=Aron1;Uid=username;Pwd=password"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.Standard&nbsp;Sybase&nbsp;System&nbsp;11: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={SYBASE&nbsp;SYSTEM&nbsp;11};Srvr=Aron1;Uid=username;Pwd=password;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;III.Intersolv&nbsp;3.10: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Driver={INTERSOLV&nbsp;3.10&nbsp;32-BIT&nbsp;Sybase};Srvr=Aron1;Uid=username; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pwd=password;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;IIII.Sybase&nbsp;SQL&nbsp;Anywhere&nbsp;(former&nbsp;Watcom&nbsp;SQL&nbsp;ODBC&nbsp;driver): <BR>&nbsp;&nbsp;&nbsp;&nbsp;"ODBC;&nbsp;Driver=Sybase&nbsp;SQL&nbsp;Anywhere&nbsp;5.0;&nbsp;DefaultDir=c:\dbfolder\;Dbf= <BR>&nbsp;&nbsp;&nbsp;&nbsp;c:\mydatabase.db;Uid=username;Pwd=password;Dsn="""""&nbsp; <BR>&nbsp;&nbsp;B.OLEDB <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Adaptive&nbsp;Server&nbsp;Anywhere&nbsp;(ASA): <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Provider=ASAProv;Data&nbsp;source=myASA"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Adaptive&nbsp;Server&nbsp;Enterprise&nbsp;(ASE)&nbsp;with&nbsp;Data&nbsp;Source&nbsp;.IDS&nbsp;file: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Sybase&nbsp;ASE&nbsp;OLE&nbsp;DB&nbsp;Provider;&nbsp;Data&nbsp;source=myASE"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;注：必须先用Data&nbsp;Administrator创建Data&nbsp;Source&nbsp;.IDS&nbsp;file&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;III.Adaptive&nbsp;Server&nbsp;Enterprise&nbsp;(ASE): <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Sybase.ASEOLEDBProvider;Srvr=myASEserver,5000;Catalog=myDBname; <BR>&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;Id=username;Password=password"&nbsp; <BR>8.Informix&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Informix&nbsp;3.30: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Dsn=’’;Driver={INFORMIX&nbsp;3.30&nbsp;32&nbsp;BIT};Host=hostname;Server=myserver;Service= <BR>&nbsp;&nbsp;&nbsp;&nbsp;service-name;Protocol=olsoctcp;Database=mydb;UID=username;PWD=myPwd&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.Informix-CLI&nbsp;2.5: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Informix-CLI&nbsp;2.5&nbsp;(32&nbsp;Bit)};Server=myserver;Database=mydb; <BR>&nbsp;&nbsp;&nbsp;&nbsp;Uid=username;Pwd=myPwd"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.IBM&nbsp;Informix&nbsp;OLE&nbsp;DB&nbsp;Provider: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Ifxoledbc.2;password=myPw;User&nbsp;ID=myUser;Data&nbsp;Source= <BR>&nbsp;&nbsp;&nbsp;&nbsp;dbName@serverName;Persist&nbsp;Security&nbsp;Info=true"&nbsp; <BR>9.Mimer&nbsp;SQL&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;I.Standard&nbsp;Security: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Driver={MIMER};Database=mydb;Uid=myuser;Pwd=mypw;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;II.&nbsp;Prompt&nbsp;for&nbsp;username&nbsp;and&nbsp;password: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Driver={MIMER};Database=mydb;"&nbsp; <BR>10.DSN&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.DSN: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"DSN=myDsn;Uid=username;Pwd=;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.File&nbsp;DSN: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"FILEDSN=c:\myData.dsn;Uid=username;Pwd=;"&nbsp; <BR>11.Excel&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Excel&nbsp;Driver&nbsp;(*.xls)};DriverId=790; <BR>&nbsp;&nbsp;&nbsp;&nbsp;Dbq=C:\MyExcel.xls;DefaultDir=c:\mypath;"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;&nbsp;"Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=C:\MyExcel.xls;Extended&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;Properties=""Excel&nbsp;8.0;HDR=Yes;IMEX=1"""&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;"HDR=Yes;"&nbsp;indicates&nbsp;that&nbsp;the&nbsp;first&nbsp;row&nbsp;contains&nbsp;columnnames,&nbsp;not&nbsp;data. <BR>&nbsp;&nbsp;&nbsp;&nbsp;"IMEX=1;"&nbsp;tells&nbsp;the&nbsp;driver&nbsp;to&nbsp;always&nbsp;read&nbsp;"intermixed"&nbsp;data&nbsp;columns&nbsp;as&nbsp;text. <BR>12.Text&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Text&nbsp;Driver&nbsp;(*.txt;&nbsp;*.csv)}; <BR>&nbsp;&nbsp;&nbsp;Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;"Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=c:\txtFilesFolder\;Extended&nbsp; <BR>&nbsp;&nbsp;&nbsp;Properties=""text;HDR=Yes;FMT=Delimited"""&nbsp; <BR>&nbsp;&nbsp;&nbsp;"HDR=Yes;"&nbsp;indicates&nbsp;that&nbsp;the&nbsp;first&nbsp;row&nbsp;contains&nbsp;columnnames,&nbsp;not&nbsp;data. <BR>13.DBF&nbsp;/&nbsp;FoxPro&nbsp; <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.standard: <BR>&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;dBASE&nbsp;Driver&nbsp;(*.dbf)};DriverID=277;Dbq=c:\mydbpath;"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.standard: <BR>&nbsp;&nbsp;&nbsp;"Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=c:\folder;Extended&nbsp;Properties= <BR>&nbsp;&nbsp;&nbsp;dBASE&nbsp;IV;User&nbsp;ID=Admin;Password=" <BR>14.Visual&nbsp;FoxPro&nbsp; <BR>&nbsp;&nbsp;A.OLE&nbsp;DB,&nbsp;OleDbConnection&nbsp;(.NET)&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Database&nbsp;container&nbsp;(.DBC): <BR>&nbsp;&nbsp;&nbsp;"Provider=vfpoledb.1;Data&nbsp;Source=C:\MyDbFolder\MyDbContainer.dbc; <BR>&nbsp;&nbsp;&nbsp;Password=MyPassWord;Collating&nbsp;Sequence=machine"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.&nbsp;Free&nbsp;table&nbsp;directory: <BR>&nbsp;&nbsp;&nbsp;"Provider=vfpoledb.1;Data&nbsp;Source=C:\MyDataDirectory\;Password=MyPassWord; <BR>&nbsp;&nbsp;&nbsp;Collating&nbsp;Sequence=general"&nbsp; <BR>&nbsp;&nbsp;B.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Database&nbsp;container&nbsp;(.DBC): <BR>&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Visual&nbsp;FoxPro&nbsp;Driver};SourceType=DBC;SourceDB= <BR>&nbsp;&nbsp;&nbsp;c:\myvfpdb.dbc;Exclusive=No;Collate=Machine;"&nbsp; <BR>&nbsp;&nbsp;&nbsp;II.Free&nbsp;Table&nbsp;directory: <BR>&nbsp;&nbsp;&nbsp;"Driver={Microsoft&nbsp;Visual&nbsp;FoxPro&nbsp;Driver};SourceType=DBF;SourceDB= <BR>&nbsp;&nbsp;&nbsp;c:\myvfpdbfolder;Exclusive=No;Collate=Machine;"&nbsp; <BR>15.Pervasive&nbsp;(没听说过这个东东) <BR>&nbsp;&nbsp;A.ODBC&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;"Driver={Pervasive&nbsp;ODBC&nbsp;Client&nbsp;Interface};ServerName=srvname;dbq=@dbname"&nbsp; <BR>&nbsp;&nbsp;B.OLE&nbsp;DB&nbsp; <BR>&nbsp;&nbsp;&nbsp;I.Standard: <BR>&nbsp;&nbsp;&nbsp;"Provider=PervasiveOLEDB;Data&nbsp;Source=C:\path"&nbsp; <BR>16.UDL&nbsp; <BR>&nbsp;&nbsp;&nbsp;"File&nbsp;Name=c:\myDataLink.udl;"<img src ="http://www.cppblog.com/ivenher/aggbug/1008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-11-09 15:16 <a href="http://www.cppblog.com/ivenher/articles/1008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用UDL文件来建立ADO连接</title><link>http://www.cppblog.com/ivenher/articles/1007.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Wed, 09 Nov 2005 07:04:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/1007.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/1007.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/1007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/1007.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/1007.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD height=40></TD></TR>
<TR>
<TD>
<TABLE class=pagefont cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD style="PADDING-TOP: 5px">使用通用数据连接文件（*.UDL，以下简称文件）来创建ADO连接，可以和ODBC一样可视化地定义要连接的数据源，从而实现数据访问的透明性。 <BR><BR>　　 1.使用UDL文件来创建ADO连接 <BR><BR>　　 创建ADO的连接，首先要设置ADO连接对象的ConnectionString属性，该属性提供所要连接的数据库类型、数据所处服务器、要访问的数据库和数据库访问的安全认证信息。比较专业的方法是在ConnectionString中直接提供以上信息，下面是访问不同类型数据源设置ConnectionString的标准： <BR>访问ODBC数据 <BR><BR>"Provider=MSDASQL;DSN=dsnName;UID=userName;PWD=userPassword;" <BR>访问ORACLE数据库 <BR>"Provider=MSDAORA;Data Source=serverName;User ID=userName; Password=userPassword;" <BR>访问MS SQL数据库 <BR>"Provider=SQLOLEDB;Data Source=serverName;Initial Catalog=databaseName; User ID=userName;Password=userPassword;" <BR>访问ACCESS 数据库 <BR>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassword;" <BR><BR>　　 上述的连接属性设置标准随着数据源的类型不同而变化，软件用户常常不习惯这种设置方式，都希望有可视化的数据源设置方法。为此Microsoft提供了通用数据连接文件（.UDL）来建立和测试ADO连接属性。ADO连接对象可以很方便地使用UDL文件来连接数据源，下面例子使用my_data1.udl来创建ADO连接。 <BR><BR>_ConnectionPtr m_pDBConn; <BR>m_pDBConn.CreateInstance(__uuidof(Connection)); <BR><STRONG><FONT color=#006400>m_pDBConn-&gt;ConnectionString ="File Name=c:\mydir\my_data1.udl";</FONT></STRONG>&nbsp; <STRONG><FONT color=#a52a2a>//注意：name=c：等号两边不能有空格<BR></FONT></STRONG>m_pDBConn-&gt;Open("","","",NULL); <BR><BR>　　 这样一来无论数据源如何变化，在软件中都可以用统一的方法编程。当数据源改变时，只要双击相应的udl文件即可可视化地设置数据源，无需更改软件。 <BR><BR>　　 因为ADO是COM接口，为了软件的可靠性，打开ADO连接时，可以加入异常处理代码。 <BR><BR>try{ <BR>m_pDBConn-&gt;Open("","","",NULL); <BR>}catch(_com_error &amp;e){ <BR>//处理异常的代码 <BR>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . <BR>m_pDBConn=NULL; <BR>} <BR><BR>　　 因为_ConnectionPtr m_pDBConn是智能指针，应在处理异常代码时将智能指针设为NULL后将自动将引用计数降为0。 <BR><BR>　　 如果不出现异常，只要在使用完m_pDBConn，只要引用Close方法即可。 <BR><BR>　　 2.创建你所需的UDL文件 <BR><BR>　　 在你所想创建UDL文件的目录中单击右键，选择从菜单 新建|Microsoft 数据连接，然后将新创建的UDL文件更改为你所希望的文件名（.UDL扩展名不能改变）。 <BR><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.cppblog.com/ivenher/aggbug/1007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-11-09 15:04 <a href="http://www.cppblog.com/ivenher/articles/1007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Visual C++中用ADO进行数据库编程 </title><link>http://www.cppblog.com/ivenher/articles/992.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Wed, 09 Nov 2005 02:49:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/992.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/992.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/992.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/992.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/992.html</trackback:ping><description><![CDATA[由 wnchg 整理<BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<P align=left><BR><BR>　</P></TD></TR>
<TR>
<TD><BR>　1. 生成应用<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>框架并初始化OLE/COM库环境 <BR><BR>　　创建一个标准的MFC AppWizard(exe)应用<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>，然后在使用ADO<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>的InitInstance函数中初始化OLE/COM库（因为ADO库是一个COM DLL库）。<BR>本例为：</TD></TR>
<TR>
<TD><PRE>　BOOL CAdotestDlg::OnInitDialog()
　{
        ::CoInitialize(NULL); //初始化OLE/COM库环境 
  } 
</PRE></TD></TR>
<TR>
<TD><A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>最后要调用 ::CoUninitialize()；//释放<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>占用的COM 资源。<BR>另外：</TD></TR>
<TR>
<TD><PRE>m_pRecordset-&gt;Close(); 注意！！！不要多次关闭！！！！！！！！！！！！
m_pConnection-&gt;Close();
m_pRecordset = NULL;
m_pConnection = NULL; </PRE></TD></TR>
<TR>
<TD>　2. 引入ADO库<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A> <BR><BR>　　使用ADO前必须在工程的stdafx.h<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>最后用直接引入符号＃import引入ADO库<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>，以使编译器能正确编译。代码如下：<BR>#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")<BR>　&nbsp; ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll）中，在其内部称为类型库。类型库描述了自治接口，以及C＋＋使用的COM vtable接口。当使用＃import指令时，在运行时Visual C＋＋需要从ADO DLL中读取这个类型库，并以此创建一组C＋＋头<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>。这些头<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>具有.tli 和.tlh扩展名，读者可以在项目的目录下找到这两个<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>。在C＋＋<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>代码中调用的ADO类要在这些<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>中定义。 <BR>&nbsp; 　<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>的第三行指示ADO对象不使用名称空间。在有些应用<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>中，由于应用<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>中的对象与ADO中的对象之间可能会出现命名冲突，所以有必要使用名称空间。如果要使用名称空间，则可把第三行<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>修改为： rename_namespace("AdoNS")。第四行代码将ADO中的EOF(<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>结束)更名为adoEOF，以避免与定义了自己的EOF的其他库冲突。 <BR><BR>　3．利用智能指针进行<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>操作 <BR><BR>　　在CaboutDlg头<A href="http://www.chinaitpower.com/Soft/Tools/File/index.html" target=_blank>文件</A>中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。<BR>　</TD></TR>
<TR>
<TD><PRE> class CAdotestDlg : public CDialog
{
     _ConnectionPtr m_pConnection;
     _RecordsetPtr m_pRecordset;
　　 ClistCtrl m_List; 
     ......
}     
</PRE></TD></TR>
<TR>
<TD>ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。<BR><BR>_ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句，如一个存储过程。<BR>_CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时，可以利用全局_ConnectionPtr接口，也可以在_CommandPtr接口里直接使用连接串。_RecordsetPtr是一个记录集对象。与以上两种对象相比，它对记录集提供了更多的控制功能，如记录锁定、游标控制等。 <BR><BR>　　在使用ADO<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>的事件响应中OnButton1加入以下代码: <BR>　</TD></TR>
<TR>
<TD><PRE>void CAdotestDlg::OnButton1() 
{
	m_List.ResetContent();
	m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
	m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针

	try
	{
		m_pConnection-&gt;Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源
		//注意：这是连接不需要用户ID或密码的open 函数
		// 否则形式为 -&gt;Open("DSN=test;uid=sa;pwd=123;","","",0); 
	

		// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
		CString strSql="select * from middle";
		BSTR bstrSQL = strSql.AllocSysString(); 
		m_pRecordset-&gt;Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
		//adOpenDynamic：动态 adLockOptimistic乐观封锁法 adCmdText：文本查询语句

		while(!m_pRecordset-&gt;adoEOF)//遍历所有记录
		{ 
			//取纪录字段值方式之一
			_variant_t TheValue; //VARIANT数据类型
			TheValue = m_pRecordset-&gt;GetCollect("BIG_NAME");//得到字段BIG_NAME的值
			if(TheValue.vt!=VT_NULL)
				m_List.AddString((char*)_bstr_t(TheValue));
			//将该值加入到列表控件中
	
			//取纪录字段值方式之二
			// _bstr_t TheValue1=m_pRecordset-&gt;Fields-&gt;GetItem("BIG_NAME")-&gt;Value;
			// CString temp=TheValue1.copy();
			// m_List.AddString(temp);

			//数据类型转换
			_variant_t vUsername,vBirthday,vID,vOld;
			TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",
			vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);


			m_pRecordset-&gt;MoveNext();//转到下一条纪录
		}
		m_pRecordset-&gt;Close();
		m_pConnection-&gt;Close();
	}
	catch (_com_error e)//异常处理
	{
		AfxMessageBox(e.ErrorMessage());
	}
	m_pRecordset-&gt;Close(); //注意！！！不要多次关闭！！！！否则会出错
	m_pConnection-&gt;Close();
	m_pRecordset = NULL;
	m_pConnection = NULL; 
} </PRE></TD></TR>
<TR>
<TD>　　<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>中通过_variant_t和_bstr_t转换COM对象和C＋＋类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。 <BR><BR>　　好，编译后该<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>就能运行了，但记住运行前要创建一个叫ADOTest的ODBC数据源。该<A href="http://www.chinaitpower.com/Dev/index.html" target=_blank>程序</A>将把表middle中的BIG_NAME字段值显示在列表控件中。<BR><BR><BR><BR>　4．执行SQL命令并取得结果记录集<BR><BR>&nbsp;&nbsp;&nbsp; 为了取得结果记录集，我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;<BR>并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");<BR>SQL命令的执行可以采用多种形式，下面我们一进行阐述。<BR><BR>(1)利用Connection对象的Execute方法执行SQL命令<BR>Execute方法的原型如下所示:</TD></TR>
<TR>
<TD><PRE>     _RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 
     其中CommandText是命令字串，通常是SQL命令。

	参数RecordsAffected是操作完成后所影响的行数, 

	参数Options表示CommandText中内容的类型，Options可以取如下值之一：
	adCmdText:表明CommandText是文本命令
	adCmdTable:表明CommandText是一个表名
	adCmdProc:表明CommandText是一个存储过程
	adCmdUnknown:未知

    Execute执行完后返回一个指向记录集的指针，下面我们给出具体代码并作说明。 
    _variant_t RecordsAffected;
    ///执行SQL命令：CREATE TABLE创建表格users,users包含四个字段:整形ID,<A href="http://www.chinaitpower.com/Dev/Programme/VC/Str/index.html" target=_blank>字符</A>串username,整形old,日期型birthday
    m_pConnection-&gt;Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
			&amp;RecordsAffected,
			adCmdText);
    ///往表格里面添加记录
    m_pConnection-&gt;Execute("INSERT INTO users(ID,username,old,birthday) VALUES (1, ''''Washington'''',25,''''1970/1/1'''')",&amp;RecordsAffected,adCmdText);
    ///将所有记录old字段的值加一
    m_pConnection-&gt;Execute("UPDATE users SET old = old+1",&amp;RecordsAffected,adCmdText);
    ///执行SQL统计命令得到包含记录条数的记录集
    m_pRecordset =  m_pConnection-&gt;Execute("SELECT COUNT(*) FROM users",&amp;RecordsAffected,adCmdText);
    _variant_t vIndex = (long)0;
    _variant_t vCount = m_pRecordset-&gt;GetCollect(vIndex);///取得第一个字段的值放入vCount变量
    上两句可以写成— _variant_t vCount = m_pRecordset-&gt;GetCollect((_variant_t)((long)0));
    m_pRecordset-&gt;Close();///关闭记录集
    CString message;
    message.Format("共有%d条记录",vCount.lVal);
    AfxMessageBox(message);///显示当前记录条数
</PRE></TD></TR>
<TR>
<TD><SPAN class=big>(2)利用Command对象来执行SQL命令</SPAN></TD></TR>
<TR>
<TD><PRE><SPAN class=big>_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand-&gt;ActiveConnection = m_pConnection;///非常关键的一句，将建立的连接赋值给它
m_pCommand-&gt;CommandText = "SELECT * FROM users";///命令字串
m_pRecordset = m_pCommand-&gt;Execute(&amp;vNULL,&amp;vNULL,adCmdText);///执行命令，取得记录集</SPAN></PRE></TD></TR>
<TR>
<TD>&nbsp;&nbsp;&nbsp; 在这段代码中我们只是用Command对象来执行了SELECT查询语句，Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 <BR><BR>(3)直接用Recordset对象进行查询取得记录集 <BR>实例——</TD></TR>
<TR>
<TD><PRE>void CGmsaDlg::OnDBSelect() 
{
    // TODO: Add your control notification handler code here
     _RecordsetPtr Rs1;  //定义Recordset对象
    _bstr_t Connect("DSN=GMS;UID=sa;PWD=;");//定义连接<A href="http://www.chinaitpower.com/Dev/Programme/VC/Str/index.html" target=_blank>字符</A>串
    _bstr_t Source ("SELECT count(*) FROM buaa.mdb010");  //要执行的SQL语句
    ::CoInitialize(NULL);    //初始化Rs1对象
        HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
       //省略对返回值hr的判断 
     Rs1-&gt;Open( Source,
            Connect,
                adOpenForwardOnly,
                    adLockReadOnly,
            -1 ); 
    _variant_t temp=Rs1-&gt;GetCollect(_variant_t((long)0));
    CString strTemp=(char* )(_bstr_t)temp;
    MessageBox("OK!"+strTemp);
}

例如 

  m_pRecordset-&gt;Open("SELECT * FROM users",
		_variant_t((IDispatch *)m_pConnection,true),
		adOpenStatic,
		adLockOptimistic,
		adCmdText);

Open方法的原型是这样的:
HRESULT Recordset15::Open ( const _variant_t &amp; Source, 
			const _variant_t &amp; ActiveConnection, 
			enum CursorTypeEnum CursorType, 
			enum LockTypeEnum LockType, 
			long Options ) 
其中：
①Source是数据查询<A href="http://www.chinaitpower.com/Dev/Programme/VC/Str/index.html" target=_blank>字符</A>串
②ActiveConnection是已经建立好的连接（我们需要用Connection对象指针来构造一个_variant_t对象) 
③CursorType光标类型，它可以是以下值之一,请看这个枚举结构:
enum CursorTypeEnum
{
	adOpenUnspecified = -1,///不作特别指定
	adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集，比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
	adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作，但对于更新原有记录的操作对你是可见的。
	adOpenDynamic = 2,///动态光标。所有<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>的操作都会立即在各用户记录集上反应出来。
	adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份，但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
};
④LockType锁定类型，它可以是以下值之一，请看如下枚举结构：
enum LockTypeEnum
{
	adLockUnspecified = -1,///未指定
	adLockReadOnly = 1,///只读记录集
	adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作，这是最安全的锁定机制
	adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
	adLockBatchOptimistic = 4，乐观分批更新。编辑时记录不会锁定，更改、插入及删除是在批处理模式下完成。
}; 
⑤Options可以取如下值之一：
	adCmdText:表明CommandText是文本命令
	adCmdTable:表明CommandText是一个表名
	adCmdProc:表明CommandText是一个存储过程
	adCmdUnknown:未知
</PRE></TD></TR>
<TR>
<TD>&nbsp;5. 记录集的遍历、更新<BR>&nbsp;&nbsp;&nbsp; 根据我们刚才通过执行SQL命令建立好的users表，它包含四个字段:ID,username,old,birthday<BR>以下的代码实现：打开记录集，遍历所有记录，删除第一条记录，添加三条记录，移动光标到第二条记录，<BR>更改其年龄，保存到<A href="http://www.chinaitpower.com/Dev/DataBase/index.html" target=_blank>数据库</A>。</TD></TR>
<TR>
<TD><PRE>_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset-&gt;Open("SELECT * FROM users",
		_variant_t((IDispatch*)m_pConnection,true),
		adOpenStatic,
		adLockOptimistic,
		adCmdText);
while(!m_pRecordset-&gt;adoEOF)
{
    vID = m_pRecordset-&gt;GetCollect(_variant_t((long)0));///取得第1列的值,从0开始计数，
    ///你也可以直接给出列的名称，如下一行
    vUsername = m_pRecordset-&gt;GetCollect("username");///取得username字段的值
    vOld = m_pRecordset-&gt;GetCollect("old");
    vBirthday = m_pRecordset-&gt;GetCollect("birthday");
    ///在DEBUG方式下的OUTPUT窗口输出记录集中的记录
    if(vID.vt != VT_NULL &amp;&amp; vUsername.vt != VT_NULL &amp;&amp; vOld.vt != VT_NULL &amp;&amp; vBirthday.vt != VT_NULL)
        TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",
		vID.lVal,
		(LPCTSTR)(_bstr_t)vUsername,
		vOld.lVal,
		(LPCTSTR)(_bstr_t)vBirthday);
    m_pRecordset-&gt;MoveNext();///移到下一条记录
}
m_pRecordset-&gt;MoveFirst();///移到首条记录
m_pRecordset-&gt;Delete(adAffectCurrent);///删除当前记录
///添加三条新记录并赋值
for(int i=0;i&lt;3;i++)
{
    m_pRecordset-&gt;AddNew();///添加新记录
    m_pRecordset-&gt;PutCollect("ID",_variant_t((long)(i+10)));
    m_pRecordset-&gt;PutCollect("username",_variant_t("叶利钦"));
    m_pRecordset-&gt;PutCollect("old",_variant_t((long)71));
    m_pRecordset-&gt;PutCollect("birthday",_variant_t("1930-3-15"));
}
m_pRecordset-&gt;Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移动到第二条记录处
m_pRecordset-&gt;PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年龄
m_pRecordset-&gt;Update();///保存到库中    </PRE></TD></TR>
<TR>
<TD>备注：多次查询可把查询过程做成一个函数ExecuteSQL让m_pRecordset获得连接指针m_pConnection查询结果</TD></TR>
<TR>
<TD><PRE>void ExecuteSQL(_ConnectionPtr  m_pConnection, _RecordsetPtr  m_pRecordset,CString strSql)
{
    //执行Select 语句
    BSTR bstrSQL = strSql.AllocSysString();           
     try
     {
        m_pRecordset-&gt;Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
            //adOpenDynamic：动态  adLockOptimistic乐观封锁法  adCmdText：文本查询语句

     }

     catch(_com_error error)
     {
        CString errorMessage;
        errorMessage.Format("%s",(LPTSTR)error.Description());
        AfxMessageBox(errorMessage);
     }
}        

//出错处理：
3127——没有找到目标表
3092——目标表已经存在
例如：
catch(const _com_error e)
{
     AfxMessageBox(e.Description());
     long errorCode=e.WCode();
     if(3127==errorCode) AfxMessageBox("表不存在");
     if(3092==errorCode) AfxMessageBox("表已经存在");
     return FALSE;
} 
    </PRE></TD></TR>
<TR>
<TD>　</TD></TR></TBODY></TABLE><img src ="http://www.cppblog.com/ivenher/aggbug/992.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-11-09 10:49 <a href="http://www.cppblog.com/ivenher/articles/992.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ADO连接字符串</title><link>http://www.cppblog.com/ivenher/articles/827.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Mon, 24 Oct 2005 08:19:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/827.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/827.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/827.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/827.html</trackback:ping><description><![CDATA[<DIV class=postTitle><A id=_f3879933b975fd50_HomePageDays_DaysList__ctl0_DayItem_DayList__ctl0_TitleUrl href="http://www.cnblogs.com/easydl/archive/2004/10/09/50344.html">www.connectionstrings.com</A> </DIV>
<DIV class=postText>
<DIV><FONT size=2><SPAN class=toplvl ondblclick=menu(sqlserver); style="CURSOR: hand" onclick=menu(sqlserver);><FONT face=Courier size=3>&nbsp;</FONT> 
<LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)">&nbsp;SQL Server </SPAN>
<UL><SPAN id=sqlserver><SPAN class=seclvl ondblclick=menu(sqlserverodbc); style="CURSOR: hand" onclick=menu(sqlserverodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=sqlserverodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard Security:</B><BR>
<DIV>"Driver={SQL Server};Server=Aron1;Database=pubs;Uid=sa;Pwd=asdasd;" </DIV><BR><BR>
<LI><B>&nbsp;Trusted connection:</B><BR>
<DIV>"Driver={SQL Server};Server=Aron1;Database=pubs;Trusted_Connection=yes;" </DIV><BR><BR>
<LI><B>&nbsp;Prompt for username and password:</B><BR>
<DIV>oConn.Properties("Prompt") = adPromptAlways<BR>oConn.Open "Driver={SQL Server};Server=Aron1;DataBase=pubs;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(sqlserveroledb); style="CURSOR: hand" onclick=menu(sqlserveroledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)">&nbsp;OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=sqlserveroledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard Security:</B><BR>
<DIV>"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;" </DIV><BR><BR>
<LI><B>&nbsp;Trusted Connection:</B><BR>
<DIV>"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;" 
<BLOCKQUOTE><I>(use serverName\instanceName as Data Source to use an specifik SQLServer instance, only SQLServer2000)</I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Prompt for username and password:</B><BR>
<DIV>oConn.Provider = "sqloledb"<BR>oConn.Properties("Prompt") = adPromptAlways<BR>oConn.Open "Data Source=Aron1;Initial Catalog=pubs;" </DIV><BR><BR>
<LI><B>&nbsp;Connect via an IP address:</B><BR>
<DIV>"Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;" 
<BLOCKQUOTE><I>(DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))</I></BLOCKQUOTE></DIV></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(sqlserveradonet); style="CURSOR: hand" onclick=menu(sqlserveradonet);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)">&nbsp;SqlConnection (.NET) </SPAN><BR><BR><SPAN id=sqlserveradonet style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard Security:</B><BR>
<DIV>"Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;" <BR><I>&nbsp;&nbsp;&nbsp;-&nbsp;or&nbsp;-</I><BR>"Server=Aron1;Database=pubs;User ID=sa;Password=asdasd;Trusted_Connection=False" <BR><I>&nbsp;&nbsp;&nbsp;(booth connection strings produces the same result)</I><BR></DIV><BR><BR>
<LI><B>&nbsp;Trusted Connection:</B><BR>
<DIV>"Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;" <BR><I>&nbsp;&nbsp;&nbsp;-&nbsp;or&nbsp;-</I><BR>"Server=Aron1;Database=pubs;Trusted_Connection=True;" <BR><I>&nbsp;&nbsp;&nbsp;(booth connection strings produces the same result)</I><BR>
<BLOCKQUOTE><I>(use serverName\instanceName as Data Source to use an specifik SQLServer instance, only SQLServer2000)</I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Connect via an IP address:</B><BR>
<DIV>"Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;" 
<BLOCKQUOTE><I>(DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))</I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Declare the SqlConnection:</B><BR>
<DIV>
<BLOCKQUOTE><I><U>C#:</U><BR>using System.Data.SqlClient;<BR>SqlConnection oSQLConn = new SqlConnection();<BR>oSQLConn.ConnectionString="my connectionstring";<BR>oSQLConn.Open(); </BLOCKQUOTE></DIV><BR><BR><U>VB.NET:</U><BR>Imports System.Data.SqlClient<BR>Dim oSQLConn As SqlConnection = New SqlConnection()<BR>oSQLConn.ConnectionString="my connectionstring"<BR>oSQLConn.Open() 
<DIV></DIV><BR><BR></I>
<BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(sqlserverother); style="CURSOR: hand" onclick=menu(sqlserverother);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)">&nbsp;Data Shape </SPAN><BR><BR><SPAN id=sqlserverother style="CURSOR: default">
<UL>
<LI><B>&nbsp;MS Data Shape</B><BR>"Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=Aron1;Initial Catalog=pubs;User ID=sa;Password=asdasd;" 
<BLOCKQUOTE><I>Want to learn data shaping? Check out 4GuyfFromRolla's <A title=http://www.4guysfromrolla.com/webtech/092599-1.shtml href="http://www.4guysfromrolla.com/webtech/092599-1.shtml">great article about Data Shaping &gt;&gt;</A></I></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(sqlserverreadmore); style="CURSOR: hand" onclick=menu(sqlserverreadmore);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)">&nbsp;Read more </SPAN><BR><BR><SPAN id=sqlserverreadmore style="DISPLAY: none; CURSOR: default">
<UL><SPAN class=seclvl ondblclick=menu(sqlserverreadmorenetprot); style="CURSOR: hand" onclick=menu(sqlserverreadmorenetprot);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)">&nbsp;How to define wich network protocol to use<BR><BR></SPAN><SPAN id=sqlserverreadmorenetprot style="DISPLAY: none; CURSOR: default">
<UL>
<LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)">
<DIV>Example:<BR>"Provider=sqloledb;Data Source=190.190.200.100,1433;<B><U>Network Library=DBMSSOCN</U></B>;Initial Catalog=pubs;User ID=sa;Password=asdasd;" <BR><BR>
<TABLE>
<TBODY>
<TR>
<TD width=100><FONT size=0><B><U>Name</U></B></FONT></TD>
<TD><FONT size=0><B><U>Network library</U></B></FONT></TD></TR>
<TR>
<TD><FONT size=0>dbnmpntw</FONT></TD>
<TD><FONT size=0>Win32 Named Pipes</FONT></TD></TR>
<TR>
<TD><FONT size=0>dbmssocn</FONT></TD>
<TD><FONT size=0>Win32 Winsock TCP/IP</FONT></TD></TR>
<TR>
<TD><FONT size=0>dbmsspxn</FONT></TD>
<TD><FONT size=0>Win32 SPX/IPX</FONT></TD></TR>
<TR>
<TD><FONT size=0>dbmsvinn</FONT></TD>
<TD><FONT size=0>Win32 Banyan Vines</FONT></TD></TR>
<TR>
<TD><FONT size=0>dbmsrpcn</FONT></TD>
<TD><FONT size=0>Win32 Multi-Protocol (Windows RPC)</FONT></TD></TR></TBODY></TABLE><FONT size=0><BR><BR><B>Important note!</B> <BR>When connecting through the SQLOLEDB provider use the syntax <I><U>Network Library</U>=dbmssocn</I><BR>and when connecting through MSDASQL provider use the syntax <I><U>Network</U>=dbmssocn</I> <BR><BR></FONT></DIV></LI></UL></SPAN></LI></UL>
<UL><SPAN class=seclvl ondblclick=menu(sqlserverreadmoreallprops); style="CURSOR: hand" onclick=menu(sqlserverreadmoreallprops);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)">&nbsp;All SqlConnection connectionstring properties<BR><BR></SPAN><SPAN id=sqlserverreadmoreallprops style="DISPLAY: none; CURSOR: default">
<UL>
<LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)">
<DIV>This table shows all connectionstring properties for the ADO.NET SqlConnection object. Most of the properties are also used in ADO. All properties and descriptions is from msdn. <BR><BR>
<TABLE class=normaltxt style="BORDER-COLLAPSE: collapse" borderColor=#aaaaaa cellSpacing=0 cellPadding=4 border=1>
<TBODY>
<TR vAlign=top bgColor=#cccccc>
<TH>Name</TH>
<TH>Default</TH>
<TH>Description</TH></TR>
<TR vAlign=top>
<TD>Application Name</TD>
<TD>&nbsp;</TD>
<TD>The name of the application, or '.Net SqlClient Data Provider' if no application name is provided.</TD></TR>
<TR vAlign=top>
<TD>AttachDBFilename<BR>-or-<BR>extended&nbsp;properties<BR>-or-<BR>Initial File Name</TD>
<TD>&nbsp;</TD>
<TD>The name of the primary file, including the full path name, of an attachable database. The database name must be specified with the keyword 'database'.</TD></TR>
<TR vAlign=top>
<TD>Connect Timeout<BR>-or-<BR>Connection Timeout</TD>
<TD>15</TD>
<TD>The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.</TD></TR>
<TR vAlign=top>
<TD>Connection Lifetime</TD>
<TD>0</TD>
<TD>When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by connection lifetime. Useful in clustered configurations to force load balancing between a running server and a server just brought on-line.</TD></TR>
<TR vAlign=top>
<TD>Connection Reset</TD>
<TD>'true'</TD>
<TD>Determines whether the database connection is reset when being removed from the pool. Setting to 'false' avoids making an additional server round-trip when obtaining a connection, but the programmer must be aware that the connection state is not being reset.</TD></TR>
<TR vAlign=top>
<TD>Current Language</TD>
<TD>&nbsp;</TD>
<TD>The SQL Server Language record name.</TD></TR>
<TR vAlign=top>
<TD>Data Source<BR>-or-<BR>Server<BR>-or-<BR>Address<BR>-or-<BR>Addr<BR>-or-<BR>Network Address</TD>
<TD>&nbsp;</TD>
<TD>The name or network address of the instance of SQL Server to which to connect.</TD></TR>
<TR vAlign=top>
<TD>Enlist</TD>
<TD>'true'</TD>
<TD>When true, the pooler automatically enlists the connection in the creation thread's current transaction context.</TD></TR>
<TR vAlign=top>
<TD>Initial Catalog<BR>-or-<BR>Database</TD>
<TD>&nbsp;</TD>
<TD>The name of the database.</TD></TR>
<TR vAlign=top>
<TD>Integrated Security<BR>-or-<BR>Trusted_Connection</TD>
<TD>'false'</TD>
<TD>Whether the connection is to be a secure connection or not. Recognized values are 'true', 'false', and 'sspi', which is equivalent to 'true'.</TD></TR>
<TR vAlign=top>
<TD>Max Pool Size</TD>
<TD>100</TD>
<TD>The maximum number of connections allowed in the pool.</TD></TR>
<TR vAlign=top>
<TD>Min Pool Size</TD>
<TD>0</TD>
<TD>The minimum number of connections allowed in the pool.</TD></TR>
<TR vAlign=top>
<TD>Network Library<BR>-or-<BR>Net</TD>
<TD>'dbmssocn'</TD>
<TD>The network library used to establish a connection to an instance of SQL Server. Supported values include dbnmpntw (Named Pipes), dbmsrpcn (Multiprotocol), dbmsadsn (Apple Talk), dbmsgnet (VIA), dbmsipcn (Shared Memory) and dbmsspxn (IPX/SPX), and dbmssocn (TCP/IP). <BR>The corresponding network DLL must be installed on the system to which you connect. If you do not specify a network and you use a local server (for example, "." or "(local)"), shared memory is used.</TD></TR>
<TR vAlign=top>
<TD>Packet Size</TD>
<TD>8192</TD>
<TD>Size in bytes of the network packets used to communicate with an instance of SQL Server.</TD></TR>
<TR vAlign=top>
<TD>Password<BR>-or-<BR>Pwd</TD>
<TD>&nbsp;</TD>
<TD>The password for the SQL Server account logging on.</TD></TR>
<TR vAlign=top>
<TD>Persist Security Info</TD>
<TD>'false'</TD>
<TD>When set to 'false', security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state. Resetting the connection string resets all connection string values including the password.</TD></TR>
<TR vAlign=top>
<TD>Pooling</TD>
<TD>'true'</TD>
<TD>When true, the SQLConnection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool.</TD></TR>
<TR vAlign=top>
<TD>User ID</TD>
<TD>&nbsp;</TD>
<TD>The SQL Server login account.</TD></TR>
<TR vAlign=top>
<TD>Workstation ID</TD>
<TD>the local computer name</TD>
<TD>The name of the workstation connecting to SQL Server.</TD></TR></TBODY></TABLE><FONT size=0><BR><BR><B>Note</B> <BR>Use ; to separate each property.<BR>If a name occurs more than once, the value from the last one in the connectionstring will be used.<BR>If you are building your connectionstring in your app using values from user input fields, make sure the user can't change the connectionstring by inserting an additional property with another value within the user value. </FONT></DIV></LI></UL></SPAN></LI></UL></SPAN></LI></UL></SPAN>
<UL></UL><SPAN class=toplvl ondblclick=menu(access); style="CURSOR: hand" onclick=menu(access);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconaccess.gif)">&nbsp;Access </SPAN>
<UL><SPAN id=access><SPAN class=seclvl ondblclick=menu(accessodbc); style="CURSOR: hand" onclick=menu(accessodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconaccess.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=accessodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard Security:</B><BR>
<DIV>"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;Uid=Admin;Pwd=;" </DIV><BR><BR>
<LI><B>&nbsp;Workgroup:</B><BR>
<DIV>"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;SystemDB=C:\mydatabase.mdw;" </DIV><BR><BR>
<LI><B>&nbsp;Exclusive:</B><BR>
<DIV>"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;Exclusive=1;Uid=admin;Pwd=" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(jetoledb); style="CURSOR: hand" onclick=menu(jetoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconaccess.gif)">&nbsp;OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=jetoledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard security:</B><BR>
<DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;User Id=admin;Password=;" </DIV><BR><BR>
<LI><B>&nbsp;Workgroup (system database):</B><BR>
<DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;Jet OLEDB:System Database=system.mdw;" </DIV><BR><BR>
<LI><B>&nbsp;With password:</B><BR>
<DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;Jet OLEDB:Database Password=MyDbPassword;" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(oracle); style="CURSOR: hand" onclick=menu(oracle);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)">&nbsp;Oracle </SPAN>
<UL><SPAN id=oracle><SPAN class=seclvl ondblclick=menu(oracleodbc); style="CURSOR: hand" onclick=menu(oracleodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=oracleodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;New version:</B><BR>
<DIV>"Driver={Microsoft ODBC for Oracle};Server=OracleServer.world;Uid=Username;Pwd=asdasd;" </DIV><BR><BR>
<LI><B>&nbsp;Old version:</B><BR>
<DIV>"Driver={Microsoft ODBC Driver for Oracle};ConnectString=OracleServer.world;Uid=myUsername;Pwd=myPassword;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(oracleoledb); style="CURSOR: hand" onclick=menu(oracleoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)">&nbsp;OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=oracleoledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard security:</B><BR>
<DIV>"Provider=msdaora;Data Source=MyOracleDB;User Id=UserName;Password=asdasd;" 
<BLOCKQUOTE><I>This one's from Microsoft, the following are from Oracle</I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Standard Security:</B><BR>
<DIV>"Provider=OraOLEDB.Oracle;Data Source=MyOracleDB;User Id=Username;Password=asdasd;" </DIV><BR><BR>
<LI><B>&nbsp;Trusted Connection:</B><BR>
<DIV>"Provider=OraOLEDB.Oracle;Data Source=MyOracleDB;OSAuthent=1;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(oracleadonet); style="CURSOR: hand" onclick=menu(oracleadonet);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)">&nbsp;OracleConnection (.NET) </SPAN><BR><BR><SPAN id=oracleadonet style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"Data Source=Oracle8i;Integrated Security=yes"; 
<BLOCKQUOTE><I>This one works only with Oracle 8i release 3 or later</I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Declare the OracleConnection:</B><BR>
<DIV>
<BLOCKQUOTE><I><U>C#:</U><BR>using System.Data.OracleClient;<BR>OracleConnection oOracleConn = new OracleConnection();<BR>oOracleConn.ConnectionString = "my connectionstring";<BR>oOracleConn.Open(); </BLOCKQUOTE></DIV><BR><BR><U>VB.NET:</U><BR>Imports System.Data.OracleClient<BR>Dim oOracleConn As OracleConnection = New OracleConnection()<BR>oOracleConn.ConnectionString = "my connectionstring"<BR>oOracleConn.Open() 
<DIV></DIV><BR><BR></I>
<BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(oradirect); style="CURSOR: hand" onclick=menu(oradirect);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)">&nbsp;Core Labs OraDirect (.NET) </SPAN><BR><BR><SPAN id=oradirect style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>"User ID=scott; Password=tiger; Host=ora; Pooling=true; Min Pool Size=0;Max Pool Size=100; Connection Lifetime=0" 
<BLOCKQUOTE>Read more at <I><A title=http://www.crlab.com/ href="http://www.crlab.com/">Core Lab</A> and the <A title=http://www.crlab.com/oranet/ href="http://www.crlab.com/oranet/">product page</A>.</I></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(oracleother); style="CURSOR: hand" onclick=menu(oracleother);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)">&nbsp;Data Shape </SPAN><BR><BR><SPAN id=oracleother style="CURSOR: default">
<UL>
<LI><B>&nbsp;MS Data Shape:</B><BR>"Provider=MSDataShape.1;Persist Security Info=False;Data Provider=MSDAORA;Data Source=orac;user id=username;password=mypw" 
<BLOCKQUOTE><I>Want to learn data shaping? Check out 4GuyfFromRolla's <A title=http://www.4guysfromrolla.com/webtech/092599-1.shtml href="http://www.4guysfromrolla.com/webtech/092599-1.shtml">great article about Data Shaping &gt;&gt;</A></I></BLOCKQUOTE></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(mysql); style="CURSOR: hand" onclick=menu(mysql);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)">&nbsp;MySQL </SPAN>
<UL><SPAN id=mysql><SPAN class=seclvl ondblclick=menu(mysqlodbc); style="CURSOR: hand" onclick=menu(mysqlodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=mysqlodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Local database:</B><BR>
<DIV>"Driver={mySQL};Server=mySrvName;Option=16834;Database=mydatabase;" </DIV><BR><BR>
<LI><B>&nbsp;Remote database:</B><BR>
<DIV>"Driver={mySQL};Server=data.domain.com;Port=3306;Option=131072;Stmt=;Database=my-database;Uid=username;Pwd=password;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(mysqloledb); style="CURSOR: hand" onclick=menu(mysqloledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)">&nbsp;OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=mysqloledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"Provider=MySQLProv;Data Source=mydb;User Id=UserName;Password=asdasd;" </DIV></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(mysqladonet); style="CURSOR: hand" onclick=menu(mysqladonet);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)">&nbsp;MySqlConnection (.NET) </SPAN><BR><BR><SPAN id=mysqladonet style="CURSOR: default">
<UL>
<LI><B>&nbsp;eInfoDesigns.dbProvider:</B><BR>
<DIV>"Data Source=server;Database=mydb;User ID=username;Password=pwd;Command Logging=false" 
<BLOCKQUOTE><I>This one is used with <A title=http://www.einfodesigns.com/ href="http://www.einfodesigns.com/">eInfoDesigns</A> dbProvider, an add-on to .NET</I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Declare the MySqlConnection:</B><BR>
<DIV>
<BLOCKQUOTE><I><U>C#:</U><BR>using eInfoDesigns.dbProvider.MySqlClient;<BR>MySqlConnection oMySqlConn = new MySqlConnection();<BR>oMySqlConn.ConnectionString = "my connectionstring";<BR>oMySqlConn.Open(); </BLOCKQUOTE></DIV><BR><BR><U>VB.NET:</U><BR>Imports eInfoDesigns.dbProvider.MySqlClient<BR>Dim oMySqlConn As MySqlConnection = New MySqlConnection()<BR>oMySqlConn.ConnectionString = "my connectionstring"<BR>oMySqlConn.Open() 
<DIV></DIV><BR><BR></I>
<BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(mysqlclient); style="CURSOR: hand" onclick=menu(mysqlclient);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)">&nbsp;SevenObjects MySqlClient (.NET) </SPAN><BR><BR><SPAN id=mysqlclient style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"Host=server; UserName=myusername; Password=mypassword;Database=mydb;" 
<BLOCKQUOTE><I>This is a freeware ADO.Net data provider from <A title=http://www.sevenobjects.com/ href="http://www.sevenobjects.com/">SevenObjects</A></I></BLOCKQUOTE></DIV></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(mysqldirect); style="CURSOR: hand" onclick=menu(mysqldirect);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)">&nbsp;Core Labs MySQLDirect (.NET) </SPAN><BR><BR><SPAN id=mysqldirect style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"User ID=root; Password=pwd; Host=localhost; Port=3306; Database=test;Direct=true; Protocol=TCP; Compress=false; Pooling=true; Min Pool Size=0;Max Pool Size=100; Connection Lifetime=0" 
<BLOCKQUOTE>Read more at <I><A title=http://www.crlab.com/ href="http://www.crlab.com/">Core Lab</A> and the <A title=http://www.crlab.com/mysqlnet/ href="http://www.crlab.com/mysqlnet/">product page</A>.</I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(interbase); style="CURSOR: hand" onclick=menu(interbase);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)">&nbsp;Interbase </SPAN>
<UL><SPAN id=interbase><SPAN class=seclvl ondblclick=menu(interbaseeasysoft); style="CURSOR: hand" onclick=menu(interbaseeasysoft);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)">&nbsp;ODBC, Easysoft </SPAN><BR><BR><SPAN id=interbaseeasysoft style="CURSOR: default">
<UL>
<LI><B>&nbsp;Local computer:</B><BR>
<DIV>"Driver={Easysoft IB6 ODBC};Server=localhost;Database=localhost:C:\mydatabase.gdb;Uid=username;Pwd=password" </DIV><BR><BR>
<LI><B>&nbsp;Remote Computer:</B><BR>
<DIV>"Driver={Easysoft IB6 ODBC};Server=ComputerName;Database=ComputerName:C:\mydatabase.gdb;Uid=username;Pwd=password" 
<BLOCKQUOTE><I>Read more about this driver: <A title=http://www.easysoft.com/products/2201/ href="http://www.easysoft.com/products/2201/">Easysoft ODBC-Interbase driver &gt;&gt;</A><BR></I></BLOCKQUOTE></DIV></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(interbaseintersolv); style="CURSOR: hand" onclick=menu(interbaseintersolv);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)">&nbsp;ODBC, Intersolv </SPAN><BR><BR><SPAN id=interbaseintersolv style="CURSOR: default">
<UL>
<LI><B>&nbsp;Local computer:</B><BR>
<DIV>"Driver={INTERSOLV InterBase ODBC Driver (*.gdb)};Server=localhost;Database=localhost:C:\mydatabase.gdb;Uid=username;Pwd=password" </DIV><BR><BR>
<LI><B>&nbsp;Remote Computer:</B><BR>
<DIV>"Driver={INTERSOLV InterBase ODBC Driver (*.gdb)};Server=ComputerName;Database=ComputerName:C:\mydatabase.gdb;Uid=username;Pwd=password" 
<BLOCKQUOTE><I>This driver are provided by <A title=http://www.datadirect-technologies.com/ href="http://www.datadirect-technologies.com/">DataDirect Technologies &gt;&gt;</A> (formerly Intersolv) </I></BLOCKQUOTE></DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(interbasesibprovider); style="CURSOR: hand" onclick=menu(interbasesibprovider);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)">&nbsp;OLE DB, SIBPROvider </SPAN><BR><BR><SPAN id=interbasesibprovider style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey" </DIV><BR><BR>
<LI><B>&nbsp;Specifying character set:</B><BR>
<DIV>"provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey;character set=ISO8859_1" </DIV><BR><BR>
<LI><B>&nbsp;Specifying role:</B><BR>
<DIV>"provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey;role=DIGITADORES" 
<BLOCKQUOTE><I><A title=http://www.sibprovider.com/en_us/default.asp href="http://www.sibprovider.com/en_us/default.asp">Read more about SIBPROvider &gt;&gt;</A> </I></BLOCKQUOTE></DIV><BR><BR></LI></UL></SPAN><BR><I>Read more about connecting to Interbase in this Borland Developer Network article <A title=http://community.borland.com/article/0,1410,27152,00.html href="http://community.borland.com/article/0,1410,27152,00.html">http://community.borland.com/article/0,1410,27152,00.html</A> </I><BR><BR></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(db2); style="CURSOR: hand" onclick=menu(db2);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondb2.gif)">&nbsp;IBM DB2 </SPAN>
<UL><SPAN id=db2><SPAN class=seclvl ondblclick=menu(db2oledb); style="CURSOR: hand" onclick=menu(db2oledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondb2.gif)">&nbsp;OLE DB, OleDbConnection (.NET) from ms </SPAN><BR><BR><SPAN id=db2oledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;TCP/IP:</B><BR>
<DIV>"Provider=DB2OLEDB;Network Transport Library=TCPIP;Network Address=XXX.XXX.XXX.XXX;Initial Catalog=MyCtlg;Package Collection=MyPkgCol;Default Schema=Schema;User ID=MyUser;Password=MyPW" </DIV><BR><BR>
<LI><B>&nbsp;APPC:</B><BR>
<DIV>"Provider=DB2OLEDB;APPC Local LU Alias=MyAlias;APPC Remote LU Alias=MyRemote;Initial Catalog=MyCtlg;Package Collection=MyPkgCol;Default Schema=Schema;User ID=MyUser;Password=MyPW" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(sybase); style="CURSOR: hand" onclick=menu(sybase);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsybase.gif)">&nbsp;Sybase </SPAN>
<UL><SPAN id=sybase><SPAN class=seclvl ondblclick=menu(sybaseodbc); style="CURSOR: hand" onclick=menu(sybaseodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsybase.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=sybaseodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard Sybase System 12 (or 12.5) Enterprise Open Client:</B><BR>
<DIV>"Driver={SYBASE ASE ODBC Driver};Srvr=Aron1;Uid=username;Pwd=password" </DIV><BR><BR>
<LI><B>&nbsp;Standard Sybase System 11:</B><BR>
<DIV>"Driver={SYBASE SYSTEM 11};Srvr=Aron1;Uid=username;Pwd=password;" 
<BLOCKQUOTE><I>Do you know a userguide for Sybase System 11, 12, 12.5? <A title=mailto:info@connectionstrings.com href="mailto:info@connectionstrings.com">E-mail the URL to connectionstrings.com now!! &gt;&gt; </A></I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Intersolv 3.10:</B><BR>
<DIV>"Driver={INTERSOLV 3.10 32-BIT Sybase};Srvr=Aron1;Uid=username;Pwd=password;" </DIV><BR><BR>
<LI><B>&nbsp;Sybase SQL Anywhere (former Watcom SQL ODBC driver):</B><BR>
<DIV>"ODBC; Driver=Sybase SQL Anywhere 5.0; DefaultDir=c:\dbfolder\;Dbf=c:\mydatabase.db;Uid=username;Pwd=password;Dsn=""""" 
<BLOCKQUOTE><I>Note! The two double quota following the DSN parameter at the end are escaped quotas (VB syntax), you may have to change this to your language specific escape syntax. The empty DSN parameter is indeed critical as not including it will result in error 7778. </BLOCKQUOTE></DIV><BR><BR><A title=http://manuals.sybase.com/onlinebooks/group-im/imcore5/conndb/@Generic__BookView/3404;cs=default;ts=default href="http://manuals.sybase.com/onlinebooks/group-im/imcore5/conndb/@Generic__BookView/3404;cs=default;ts=default">Read more in the Sybase SQL Anywhere User Guide &gt;&gt;</A> </I>
<BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(sybaseoledb); style="CURSOR: hand" onclick=menu(sybaseoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconsybase.gif)">&nbsp;OLE DB </SPAN><BR><BR><SPAN id=sybaseoledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Adaptive Server Anywhere (ASA):</B><BR>
<DIV>"Provider=ASAProv;Data source=myASA" 
<BLOCKQUOTE><I><A title=http://manuals.sybase.com/onlinebooks/group-sas/awg0702e/dbugen7/@ebt-link;pt=13894;uf=0?target=0;window=new;showtoc=true;book=dbugen7 href="http://manuals.sybase.com/onlinebooks/group-sas/awg0702e/dbugen7/@ebt-link;pt=13894;uf=0?target=0;window=new;showtoc=true;book=dbugen7">Read more in the ASA User Guide &gt;&gt;</A> </I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Adaptive Server Enterprise (ASE) with Data Source .IDS file:</B><BR>
<DIV>"Provider=Sybase ASE OLE DB Provider; Data source=myASE" 
<BLOCKQUOTE><I>Note that you must create a Data Source .IDS file using the Sybase Data Administrator. These .IDS files resemble ODBC DSNs. </I></BLOCKQUOTE></DIV>
<LI><B>&nbsp;Adaptive Server Enterprise (ASE):</B><BR>
<DIV>"Provider=Sybase.ASEOLEDBProvider;Srvr=myASEserver,5000;Catalog=myDBname;User Id=username;Password=password" <BR><I>&nbsp;&nbsp;&nbsp;- some reports on problem using the above one, try the following as an alternative -</I><BR><BR>"Provider=Sybase.ASEOLEDBProvider;Server Name=myASEserver,5000;Initial Catalog=myDBname;User Id=username;Password=password" 
<BLOCKQUOTE><I>This one works only from Open Client 12.5 where the server port number feature works,燼llowing fully qualified connection strings to be used without defining燼ny .IDS Data Source files. </I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(informix); style="CURSOR: hand" onclick=menu(informix);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinformix.gif)">&nbsp;Informix </SPAN>
<UL><SPAN id=informix><SPAN class=seclvl ondblclick=menu(informixodbc); style="CURSOR: hand" onclick=menu(informixodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinformix.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=informixodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Informix 3.30:</B><BR>
<DIV>"Dsn='';Driver={INFORMIX 3.30 32 BIT};Host=hostname;Server=myserver;Service=service-name;Protocol=olsoctcp;Database=mydb;UID=username;PWD=myPwd </DIV><BR><BR>
<LI><B>&nbsp;Informix-CLI 2.5:</B><BR>
<DIV>"Driver={Informix-CLI 2.5 (32 Bit)};Server=myserver;Database=mydb;Uid=username;Pwd=myPwd" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(informixoledb); style="CURSOR: hand" onclick=menu(informixoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconinformix.gif)">&nbsp;OLE DB </SPAN><BR><BR><SPAN id=informixoledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;IBM Informix OLE DB Provider:</B><BR>
<DIV>"Provider=Ifxoledbc.2;password=myPw;User ID=myUser;Data Source=dbName@serverName;Persist Security Info=true" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(mimer); style="CURSOR: hand" onclick=menu(mimer);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmimer.gif)">&nbsp;Mimer SQL </SPAN>
<UL><SPAN id=mimer><SPAN class=seclvl ondblclick=menu(mimerodbc); style="CURSOR: hand" onclick=menu(mimerodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconmimer.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=mimerodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard Security:</B><BR>
<DIV>"Driver={MIMER};Database=mydb;Uid=myuser;Pwd=mypw;" </DIV><BR><BR>
<LI><B>&nbsp;Prompt for username and password:</B><BR>
<DIV>"Driver={MIMER};Database=mydb;" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(postgre); style="CURSOR: hand" onclick=menu(postgre);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconpostgre.gif)">&nbsp;PostgreSQL </SPAN>
<UL><SPAN id=postgre><SPAN class=seclvl ondblclick=menu(postgresqldirect); style="CURSOR: hand" onclick=menu(postgresqldirect);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconpostgre.gif)">&nbsp;Core Labs PostgreSQLDirect (.NET) </SPAN><BR><BR><SPAN id=postgresqldirect style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"User ID=root; Password=pwd; Host=localhost; Port=5432; Database=testdb;Pooling=true; Min Pool Size=0; Max Pool Size=100; Connection Lifetime=0" 
<BLOCKQUOTE>Read more at <I><A title=http://www.crlab.com/ href="http://www.crlab.com/">Core Lab</A> and the <A title=http://www.crlab.com/pgsqlnet/ href="http://www.crlab.com/pgsqlnet/">product page</A>.</I></BLOCKQUOTE></DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(dsn); style="CURSOR: hand" onclick=menu(dsn);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondsn.gif)">&nbsp;DSN </SPAN>
<UL><SPAN id=dsn><SPAN class=seclvl ondblclick=menu(dsnodbc); style="CURSOR: hand" onclick=menu(dsnodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondsn.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=dsnodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;DSN:</B><BR>
<DIV>"DSN=myDsn;Uid=username;Pwd=;" </DIV><BR><BR>
<LI><B>&nbsp;File DSN:</B><BR>
<DIV>"FILEDSN=c:\myData.dsn;Uid=username;Pwd=;" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(excel); style="CURSOR: hand" onclick=menu(excel);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)">&nbsp;Excel </SPAN>
<UL><SPAN id=excel><SPAN class=seclvl ondblclick=menu(excelodbc); style="CURSOR: hand" onclick=menu(excelodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=excelodbc style="CURSOR: default">
<UL>
<LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"><B>&nbsp;Standard:</B><BR>
<DIV>"Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=C:\MyExcel.xls;DefaultDir=c:\mypath;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(exceloledb); style="CURSOR: hand" onclick=menu(exceloledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)">&nbsp;OLE DB </SPAN><BR><BR><SPAN id=exceloledb style="CURSOR: default">
<UL>
<LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"><B>&nbsp;Standard:</B><BR>
<DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""</B>" 
<BLOCKQUOTE><I>"HDR=Yes;" indicates that the first row contains columnnames, not data</I></BLOCKQUOTE>
<BLOCKQUOTE><I>"IMEX=1;" tells the driver to always read "intermixed" data columns as text</I></BLOCKQUOTE>
<BLOCKQUOTE><I>TIP! SQL syntax: "SELECT * FROM [sheet1$]" - i.e. worksheet name followed by a "$" and wrapped in "[" "]" brackets.</I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(text); style="CURSOR: hand" onclick=menu(text);>
<LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)">&nbsp;Text </SPAN>
<UL><SPAN id=text><SPAN class=seclvl ondblclick=menu(textodbc); style="CURSOR: hand" onclick=menu(textodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=textodbc style="CURSOR: default">
<UL>
<LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"><B>&nbsp;Standard:</B><BR>
<DIV>"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(textoledb); style="CURSOR: hand" onclick=menu(textoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)">&nbsp;OLE DB </SPAN><BR><BR><SPAN id=textoledb style="CURSOR: default">
<UL>
<LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"><B>&nbsp;Standard:</B><BR>
<DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\txtFilesFolder\;Extended Properties=""text;HDR=Yes;FMT=Delimited""" 
<BLOCKQUOTE><I>"HDR=Yes;" indicates that the first row contains columnnames, not data</I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(dbf); style="CURSOR: hand" onclick=menu(dbf);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondbf.gif)">&nbsp;DBF / FoxPro </SPAN>
<UL><SPAN id=dbf><SPAN class=seclvl ondblclick=menu(dbfodbc); style="CURSOR: hand" onclick=menu(dbfodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondbf.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=dbfodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;standard:</B><BR>
<DIV>"Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=c:\mydbpath;" </DIV><BR><BR></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(dbfoledb); style="CURSOR: hand" onclick=menu(dbfoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/icondbf.gif)">&nbsp;OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=dbfoledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;standard:</B><BR>
<DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\folder;Extended Properties=dBASE IV;User ID=Admin;Password=" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(vfoxpro); style="CURSOR: hand" onclick=menu(vfoxpro);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconvfoxpro.gif)">&nbsp;Visual FoxPro </SPAN>
<UL><SPAN id=vfoxpro><SPAN class=seclvl ondblclick=menu(vfoxprooledb); style="CURSOR: hand" onclick=menu(vfoxprooledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconvfoxpro.gif)">&nbsp;OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=vfoxprooledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Database container (.DBC):</B><BR>
<DIV>"Provider=vfpoledb.1;Data Source=C:\MyDbFolder\MyDbContainer.dbc;Password=MyPassWord;Collating Sequence=machine" </DIV><BR><BR>
<LI><B>&nbsp;Free table directory:</B><BR>
<DIV>"Provider=vfpoledb.1;Data Source=C:\MyDataDirectory\;Password=MyPassWord;Collating Sequence=general" </DIV>
<BLOCKQUOTE><A title=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fox7help/html/dggrfOLEDBProviderforVisualFoxPro.asp href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fox7help/html/dggrfOLEDBProviderforVisualFoxPro.asp">Read more (Microsoft msdn) &gt;&gt;</A></I></BLOCKQUOTE></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(vfoxproodbc); style="CURSOR: hand" onclick=menu(vfoxproodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconvfoxpro.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=vfoxproodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Database container (.DBC):</B><BR>
<DIV>"Driver={Microsoft Visual FoxPro Driver};SourceType=DBC;SourceDB=c:\myvfpdb.dbc;Exclusive=No;Collate=Machine;" </DIV><BR><BR>
<LI><B>&nbsp;Free Table directory:</B><BR>
<DIV>"Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=c:\myvfpdbfolder;Exclusive=No;Collate=Machine;" 
<BLOCKQUOTE><I>"Collate=Machine" is the default setting, for other settings check the <A title=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/lr30b_11.asp href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/lr30b_11.asp">list of supported collating sequences &gt;&gt;</A></I></BLOCKQUOTE></DIV></LI></UL></SPAN><BR><I>Microsoft Visual Foxpro site: <A title=http://msdn.microsoft.com/vfoxpro href="http://msdn.microsoft.com/vfoxpro">http://msdn.microsoft.com/vfoxpro</A> </I><BR><BR></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(pervasive); style="CURSOR: hand" onclick=menu(pervasive);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconpervasive.gif)">&nbsp;Pervasive </SPAN>
<UL><SPAN id=pervasive><SPAN class=seclvl ondblclick=menu(pervasiveodbc); style="CURSOR: hand" onclick=menu(pervasiveodbc);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconpervasive.gif)">&nbsp;ODBC </SPAN><BR><BR><SPAN id=pervasiveodbc style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"Driver={Pervasive ODBC Client Interface};ServerName=srvname;dbq=@dbname" 
<BLOCKQUOTE><I><A title=http://www.pervasive.com/library/index.asp?_portal=ODBC href="http://www.pervasive.com/library/index.asp?_portal=ODBC">Pervasive ODBC info &gt;&gt;</A></I></BLOCKQUOTE></DIV></LI></UL></SPAN><SPAN class=seclvl ondblclick=menu(pervasiveoledb); style="CURSOR: hand" onclick=menu(pervasiveoledb);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconpervasive.gif)">&nbsp;OLE DB </SPAN><BR><BR><SPAN id=pervasiveoledb style="CURSOR: default">
<UL>
<LI><B>&nbsp;Standard:</B><BR>
<DIV>"Provider=PervasiveOLEDB;Data Source=C:\path" 
<BLOCKQUOTE><I><A title=http://www.pervasive.com/library/index.asp?_portal=OLEDB href="http://www.pervasive.com/library/index.asp?_portal=OLEDB">Pervasive OLE DB info &gt;&gt;</A></I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><SPAN class=toplvl ondblclick=menu(udl); style="CURSOR: hand" onclick=menu(udl);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconudl.gif)">&nbsp;UDL </SPAN>
<UL><SPAN id=udl><SPAN class=seclvl ondblclick=menu(udludl); style="CURSOR: hand" onclick=menu(udludl);>
<LI style="LIST-STYLE-IMAGE: url(icon/iconudl.gif)">&nbsp;UDL </SPAN><BR><BR><SPAN id=udludl style="CURSOR: default">
<UL>
<LI><B>&nbsp;UDL:</B><BR>
<DIV>"File Name=c:\myDataLink.udl;" </DIV></LI></UL></SPAN></SPAN></LI></UL></FONT></LI></DIV></DIV><img src ="http://www.cppblog.com/ivenher/aggbug/827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2005-10-24 16:19 <a href="http://www.cppblog.com/ivenher/articles/827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>