深入CursorAdapter(二)
来源:优易学  2011-12-9 18:17:38   【优易学:中国教育考试门户网】   资料下载   IT书店

  在 VFP8 中新增的 CursorAdapter 基类提供一个统一、易用的数据接口。Doug Hennig 在这个月的文章中演示了怎样使用 CursorAdapter 来访问本地数据和 ODBC、ADO和XML这样的远程数据——讨论了使用各种数据源相应的特殊要求和实现途径。

  正文:
  如我在上一篇文章中所提到的那样,在VFP8中一个最重要的、也是最精彩的新功能是新的 CursorAdapter 基类。在那篇文章中,我们研究了一下 CursorAdapter 的属性、事件和方法,并讨论了它相对于远程视图、SQL PassThrough(SPT)、ADO和XML的优势。
  在开始使用 CursorAdapter 之前,你需要根据要访问的是本地数据还是通过ODBC、ADO或者XML的远程数据源的不同,注意这个类所相应的不同的特殊要求。这个月的文章就讲述了使用各种数据源的细节。

  使用本地数据源

  ×××××××
  尽管我们很清楚 CursorAdapter 是试图用来标准化和简化对非VFP数据的访问方式的,不过你还是可以把它当作是 Cursor 的代替品用它来访问VFP数据:只要把它的 DataSourceType 属性设置成 "Native"。为什么要这么做呢?因为你的应用程序将来可能会需要升迁——那时候你就可以把 DataSourceType 属性设置成其它几个选项之一(当然可能还需要修改其它几个属性,例如设置连接信息等等),就能轻松的切换到另一种数据库引擎,例如SQL Server。
  当 DataSourceType 属性的设置为 "Native" 的时候,VFP 会忽略它的 DataSource 属性。SelectCmd 属性必须是一个 SQL Select 语句(而不是一个 USE 命令或表达式),这就意味着你用 CursorAdapter 不是直接操作本地表而是操作一个类似于本地视图那样的东西。你还必须确保VFP能够找到出现在那个 Select 语句中的任何表,因此,如果这些表不在当前路径中,那么你就需要设置一下路径或者打开这些表所属的数据库。此外,就跟用视图一样,如果你想让这个 Cursor 是可更新的,你还必须设置好那些与更新相关的属性(KeyFieldList、Tables、UpdatableFieldlist 和 UpdateNameList)。
  下面的例子(文章附件 NativeExample.prg)会用 VFP 示例数据库中的 Customer 表建立一个可更新的 Cursor:
  local loCursor as CursorAdapter, laErrors[1]
  Open database (_samples + 'data\testdata')
  with loCursor
  .Alias = 'customercursor'
  .DataSourceType = 'Native'
  .SelectCmd = "Select CUST_ID, COMPANY, CONTACT FROM CUSTOMER " +
  "WHERE COUNTRY = 'Brazil'"
  .KeyFieldList = 'CUST_ID'
  .Tables = 'CUSTOMER'
  .UpdatableFieldList = 'CUST_ID, COMPANY, CONTACT'
  .UpdateNamelist = 'CUST_ID CUSTOMER.CUST_ID, '+
  'COMPANY CUSTOMER.COMPANY, CONTACT CUSTOMER.CONTACT'

  if .CursorFill()
  browse
  tableupdate(1)
  else
  aerror(laErrors)
  messagebox(laErrors[2])
  endif .CursorFill()
  endwith
  close databases all

  使用 ODBC
  ×××××
  ODBC 是 DataSourceType 属性四种设置中最简单的一种。把 DataSource 设置为一个打开了的 ODBC 连接句柄、设置一下常用的属性、然后调用 CursorFill 来取得数据。如果你设好了 KeyFieldList、Tables、UpdatableFieldList 和 UpdateNameList 属性,VFP 会自动把你对数据的任何改动转换成相应的 UPDATE、INSERT、和 DELETE 语句来把改动提交到后台数据源。如果你想用的是一个存储过程,那么要相应的设置 *Cmd、*CmdDataSource 和 *CmdDataSourceType 属性(* 代表 “Delete”、“Insert”或“Update”)。
  这里是附件 ODBCExample.prg 中的一个例子,它调用 Sql Server 自带的 NorthWind 数据库中的 CustOrderHist 存储过程来取得销售给某个客户的单位产品总数。
  local lcConnString, loCursor as CursorAdapter, laErrors[1]
  lcConnString = 'driver=SQL Server;server=(local);database=Northwind;uid=sa;pwd=;"+
  "trusted_connection=no'

  ** 把上面连接字符串中的密码改成你的SQL Server 登录的密码
  loCursor = createobject('CursorAdapter')
  with loCursor
  .Alias = 'Customerhistory'
  .DataSourceType = 'ODBC'
  .DataSource = SQLStringConnect(lcConnString)
  .SelectCmd = "exec CustOrderhist 'ALFKI'"

  if .CursorFill()
  browse
  else
  aerror(laErrors)
  messagebox(laErrors[2])
  endif .CursorFill()
  endwith

  使用 ADO
  ××××
  与使用 ODBC 相比,使用 ADO 要多一些需要操心的事情:
  ×× DataSource 必须被设置成一个 ADO RecordSet,而且这个 RecordSet 的 ActiveConnection 属性需要被设置成一个打开了的 ADO Connection 对象。
  ×× 如果你想要使用一个参数化查询(与下载全部数据相比,这可能是更常用的方式),你必须把一个 ADO Command 对象作为第四个参数传递给 CursorFill 方法,而且这个 Command 对象的 ActiveConnection 属性需要被设置成一个打开了的 ADO Connection 对象。VFP 会为你照顾好填充 Command 对象的参数化集合的事情(它通过分析 SelectCmd 来找出参数),不过参数所包含的值当然还是必须在有效取值范围内的。
  ×× 在数据环境中只有一个使用了 ADO 的 CursorAdapter 这样的情况是比较简单的:如果需要的话,你可以把 UseDEDataSource 属性设置成 .T.,然后根据你的需要把数据环境的 DataSource 和 DataSourceType 属性设置成 CursorAdapter。不过,如果数据环境中有多个 CursorAdapter 的话,这种办法就无效了。原因是 DataEnvironment.DataSource 所引用的 ADO RecordSet 只能包含一个 CursorAdapter 的数据;当你为第二个 CursorAdapter 调用 CursorFill 方法的时候,会出现 “RecordSet is already open (RecordSet 记录集已经打开)”的错误。所以,如果你的数据环境中有超过一个的 CursorAdapter,你必须要把 UseDEDataSource 设置成 .F.,并自行管理每个 CursorAdapter 的 DataSource 和 DataSourceType 属性(或者你可以使用一个能够管理这种情况的 DataEnvironment 的子类)。
  附件 ADOExample.prg 中的示例代码演示了怎样借助一个 ADO Command 对象来取得数据。这个示例还演示了使用 VFP8 中新的结构化错误处理的功能。对 ADO Connection 对象的 Open 方法的调用被封装在一个 TRY...CATCH...ENDTRY 语句中,以捕捉调用这个方法失败的时候将会出现的 COM 错误。
  local loConn as ADODB.Connection,
  loCommand as ADODB.Command,
  loException as Exception,
  loCursor as CursorAdapter,
  lcCountry,
  laErrors[1]
  loConn = createobject('ADODB.Connection')
  with loConn
  .ConnectionString = 'provider=SQLOLEDB.1;data source=(local);' +
  'initial catalog=Northwind;uid=sa;pwd=dhennig;trusted_connection=no'
  && 把上面连接字符串中的密码改成你的SQL Server 登录的密码
  try
  .Open()
  catch to loException
  messagebox(loException.Message)
  cancel
  endtry
  endwith
  loCommand = createobject('ADODB.Command')
  loCursor = createobject('CursorAdapter')
  with loCursor
  .Alias = 'Customers'
  .DataSourceType = 'ADO'
  .DataSource = createobject('ADODB.RecordSet')
  .SelectCmd = 'select * from customers where country=?lcCountry'
  lcCountry = 'Brazil'
  .DataSource.ActiveConnection = loConn
  loCommand.ActiveConnection = loConn
  if .CursorFill(.F., .F., 0, loCommand)
  browse
  else
  aerror(laErrors)
  messagebox(laErrors[2])
  endif .CursorFill(.F., .F., 0, loCommand)
  endwith
  使用 XML
  ××××

[1] [2] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训