打印本文 打印本文 关闭窗口 关闭窗口
VC++程序员应当如何阅读ADO文档
作者:武汉SEO闵涛  文章来源:敏韬网  点击数4431  更新时间:2009/4/23 10:41:00  文章录入:mintao  责任编辑:mintao
IANT * RecordsAffected,

        long Options );  // Connection

_RecordsetPtr Execute( VARIANT * RecordsAffected, VARIANT * Parameters,

        long Options );  // Command

_RecordsetPtr NextRecordset( VARIANT * RecordsAffected );  // Recordset

参数RecordsAffected与Parameters都是指向Variant的指针。Parameters是一个传入参数,指向一个包含一个或一组参数信息的Variant的地址,将决定命令执行的内容。RecordsAffected是一个传出参数,指向一个包含该方法返回时影响行的数目的Variant的地址。

在Command对象的Execute方法中,如果只是没有参数的话,需要将Parameters设置为&vtMissing (推荐使用)或者一个空指针(NULL)。如果传递的是一个空指针,那么等价的vtMissing会被传递并完成操作。

在所有的方法中,通过设置RecordsAffected为空指针可以指示不需返回被影响的记录的数目。此时,这个空指针实际成为了指示该方法抛弃被影响记录数目的指示器。

因此,如下的编码是有效的:

pConnection->Execute("commandText", NULL, adCmdText);

pCommand->Execute(NULL, NULL, adCmdText);

pRecordset->NextRecordset(NULL);

 

错误的处理

在COM中,大多数的操作总是返回一个HRESULT值说明该函数是否被成功完成。编译指示符#import为所有源方法和属性提供了封装好的代码并检查返回的HRESULT值。如果HRESULT指示失败,这些封装代码将会通过调用以HRESULT为参数的_com_issue_errorex()抛出一个COM错误。COM错误对象将在try-catch块中被捕获(出于效率的考虑,实际捕获的是一个_com_error对象的引用指针)。

记住,由ADO操作失败产生的错误才是ADO错误。由下层提供者返回的错误以Connection对象中Errors集合中的一个Error对象的形式出现。

编译指示符#import只能为在ADO.dll中声明的方法和属性提供错误处理例程。因此,你可以基于同样的错误处理机制编写自己的错误检查宏或内置函数。参见《Visual C++扩展》以及本文后续的示例代码。

 

在VC++与VB中编码时的约定

下面是ADO文档中关于如何使用VB和VC++编写代码的一个概览。

 

声明一个ADO对象

在VB中,一个ADO对象变量(此处以Recordset对象为例)如下声明:

Dim rst As ADODB.Recordset

子句"ADODB.Recordset"是在注册表中登记的Recordset对象的ProgID。而一个Record对象的实例如下声明: Dim rst As New ADODB.Recordset

或者:

Dim rst As ADODB.Recordset

Set rst = New ADODB.Recordset

而在VC++中,#import为所有的ADO对象生成了智能的指针类型。比如一个指向_Recordset对象的指针变量的数据类型为_RecordsetPtr,并如下声明:

_RecordsetPtr  rs;

而一个_Recordset对象的实例则如下声明:

_RecordsetPtr  rs("ADODB.Recordset");

或者:

_RecordsetPtr  rs;

rs.CreateInstance("ADODB.Recordset");

或者:

_RecordsetPtr  rs;

rs.CreateInstance(__uuidof(_Recordset));

当CreateInstance方法被成功调用后,该变量可被如此使用:rs->Open(...);

注意,如果变量是一个类的实例则用"."操作符,若是一个指向实例的指针则应使用"->"操作符。

一个变量能通过两种方式被使用。因为"->"操作符被重载,允许一个对象实例类似一个接口指针那样被使用;"->"操作符返回该指针;而由这个返回的指针访问_Recordset对象的成员。

 

编写省略String参数的代码

当你需要利用VB编写省略String参数的代码时,只需简单的略掉该操作数即可。但在VC++中,你必须指定该操作数为一个包含空字符串的_bstr_t变量:_bstr_t strMissing(L"");

 

编写省略Variant参数的代码

当你需要利用VB编写省略Variant参数的代码时,只需简单的略掉该操作数即可。但在VC++中,你必须指定所有的操作数。编写省略Variant参数的代码只需将该Variant设为专门的值,可以定义一个值为DISP_E_PARAMNOTFOUND、类型为VT_ERROR的_variant_t。还可以使用#import编译指示符提供的与之等价的常量vtMissing。

_variant_t  vtMissingYours(DISP_E_PARAMNOTFOUND, VT_ERROR);

或者:

...vtMissing...;

 

声明一个Variant

在VB中,一个Variant如下被声明:

Dim VariableName As Variant

在VC++中,定义一个_variant_t型的变量即可。主要有以下几种形式。注意:这些声明只是你在变成时刻采用的一个粗略的思路。

_variant_t  VariableName(value);

_variant_t  VariableName((data type cast) value);

_variant_t  VariableName(value, VT_DATATYPE);

_variant_t  VariableName(interface * value, bool fAddRef = true);

 

使用Variants数组

在VB中,利用Dim语句可以进行Variant数组的编程,并可以使用Array的函数。见如下示例:

Public Sub ArrayOfVariants

Dim cn As ADODB.Connection

Dim rs As ADODB.Recordset

Dim fld As ADODB.Field

 

cn.Open "DSN=pubs", "sa", ""

rs = cn.OpenSchema(adSchemaColumns, _

                     Array(Empty, Empty, "authors", Empty))

For Each fld in rs.Fields

   Debug.Print "Name = "; fld.Name

Next fld

rs.Close

cn.Close

End Sub

以下的代码演示了如何通过一个_variant_t使用一个SafeArray数组。注意注释对应了编码的步骤。

1.再一次的,TESTHR()内置函数被定义以利用预存的错误处理机制。

2.如果你只需要一个一维数组,你可以使用SafeArrayCreateVector,而非SAFEARRAYBOUND声明与SafeArrayCreate函数。下面的代码使用了SafeArrayCreate:

   SAFEARRAYBOUND   sabound[1];

   sabound[0].lLbound = 0;

   sabound[0].cElements = 4;

   pSa = SafeArrayCreate(VT_VARIANT, 1, sabound);

3.枚举常量adSchemaColumns定义的模式,决定了与TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME和COLUMN_NAME四列相联系。为此,一个有四个Variant元素的数组被创建。而对应于第三列TABLE_NAME的值被设置。

由若干列组成的返回的Recordset只是对应的所有列的一个子集,并且每一行的值保持了一一对应。

4.熟悉SafeArrays的人也许会对退出前没有调用SafeArrayDestroy()感到惊奇。实际上,在这种情况下调用SafeArrayDestroy()会导致一个运行时的异常发生。这是因为vtCriteria的析构函数会在_variant_t超出使用范围时调用VariantClear(),从而释放SafeArray。只调用SafeArrayDestroy,而没有手动清除_variant_t,将会导致析构函数试图去清除一个无效的SafeArray指针。如果要调用SafeArrayDestroy(),那么代码应该象这样:

   TESTHR(SafeArrayDestroy(pSa));

   vtCriteria.vt = VT_EMPTY;

   vtCriteria.parray = NULL;

实际更像是让_variant_t管理SafeArray。

 

完整的代码如下:

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \

   no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>

 

// Note 1

inline void TESTHR( HRESULT _hr )

   { if FAILED(_hr) _com_issue_error(_hr); }

 

void main(void)

{

   CoInitialize(NULL);

   try

   {

  

上一页  [1] [2] [3] [4] [5] [6]  下一页

打印本文 打印本文 关闭窗口 关闭窗口