我同意ODBC速度不低于其他连接方式的的观点,虽然我只在VFP6下读取(不写到远程数据)数据。
例如我在VFP下通过ODBC建立远程试图,只在需要使用的时候使用select * from database!view to tabl的方式访问远程数据,其读取速度并不低于用PB编写的通过直接连接的方式某些程序。
另外上述观点中我不支持使用大量临时表的做法,甚至是层层嵌套的使用。这对查询速度影响太大!
MS 早就嚷着要改进 VFP 对 SQL Server 的支持。
有的人只是简单的以为,这种改进只针对 SQL Server,这时不对的——VFP 是 Windows 平台下通用的数据库开发系统,除了针对 DBF 系列有特别的优化以外,一般不会偏于其他某一个数据库!
在我们猜测 VFP 8 对远程数据访问(不使用“对 SQL Server 的支持”)的改进时,我原先的想法是这样的:
可能一:提供一种基于 OLE DB 的全新的解决方案(类似于用 OLE DB 代替远程视图和SPT 用的 ODBC)
可能二:像 VB 6 那样的程度提供对ADO支持。
我本人偏向第一种情况!
……
VFP 8 beta 发布以后,看了一些文档,发现我的预测是错误的!MS 并没有像我期望的那样更换 VFP 访问远程数据的基础引擎(我的两种猜测都是用 OLE DB 换 ODBC ,只是表现不同),MS 的方案更平和,提供了更好的向下兼容性。这就是 CursorAdapter 类,这时一个新的 base class,我对他的认识概括起来是一句话:
&& 提供一种标准接口封装VFP现有的 5 种数据访问方案!!!
所谓 4 种数据访问方案,是这样理解的:
1.传统的 访问 DBF 系列数据的方式:use table...
2.传统的基于 ODBC 的远程视图
3.传统的基于 ODBC 的 SPT
4.基于 OLE DB 的 ADO
5.基于 XML 的 COM 组件或者 Web Service
6.各种自定义方式
所以,远远不止 5 种!
CursorAdapter 核心功能就是提供任意数据源到传统 VFP Cursor(游标、光标)的转换,这种转换时需要用户自己进行的,它的特色是转换的代码可以很规整的嵌入这个 CursorAdapter 中,这就是前面说的:一种标准接口!
可以这样认为,在任意数据源到 cursor 的转化过程中,CursorAdapter 什么都没有作,一切还是用户自己用代码完成,该对象只是给出了一个完美、统一的借口封装!
看几个例子:
例一:本地数据
Define CLASS CustomersData as CursorAdapter
*-- Let's define the DataSourceType as "Native" (VFP data)
DataSourceType="Native"
*-- Let's define the name of the alias that should be created.
Alias="curCustomers"
*-- Let's define the command that will generate the data to fill the cursor.
SelectCmd = "select * from Customer"
Procedure Init
*-- Once the object is created, let磗 fill the cursor.
this.CursorFill()
EndProc
EndDefine
使用:
oCustomersData = CreateObject("CustomersData")
Browse
例二(SPT):
Define CLASS CustomersData as CursorAdapter
*-- Now, we want to define the type of the data source as ODBC
DataSourceType="ODBC"
Alias="curCustomers"
*-- We can define a "Cursor Schema"
CursorSchema = ;
"customerid c(5),companyname c(30),contactname c(30),"+;
" contacttitle c(30), address c(30), city c(30), country"+;
" c(30)"
SelectCmd = ;
"select customerid, companyname, contactname, "+;
" contacttitle, address, city, country from Customers"
*-- Add a property at run-time that holds a Connection Handle.
This.AddProperty('Connection',;
SQLSTRINGCONNECT(;
"Driver=SQL Server;Server=(local);"+;
"Description=Northwind, Int Security;"+;
"DATABASE=Northwind;uid=sa;pwd=;"))
*-- The data source is our Connection Handle
This.DataSource = This.Connection
This.CursorFill()
EndProc
EndDefine
例三(WEB Service):
Define CLASS WishListData as CursorAdapter
*-- Time to set the source type to "XML"!
DataSourceType="XML"
Alias="curWishList"
Procedure Init
*-- Set the SelectCmd property to the method
*-- that will return some XML data.
This.SelectCmd = "this.GetXml()"
*-- Fill the cursor.
This.CursorFill()
EndProc
Procedure GetXml
*-- Access our beloved UT磗 Web Service over ther Internet
*-- and get some data, Sir!
loUniversalThread=Createobject("mssoap.soapclient30")
loUniversalThread.mssoapinit(;
"http://www.universalthread.com/WebService/VisualFoxPro.wsdl")
RETURN lcXML
EndProc
EndDefine
例四:(ADO)
Define CLASS CustomersData as xCursor
Procedure Init
*-- Our Source Type now is "ADO"
This.DataSourceType = "ADO"
*-- We磍l add a property to store an ADO Connection object.
This.AddProperty('oConn',;
NewObject("ADODB.Connection"))
*-- And another property to store an ADO RecordSet object.
This.AddProperty('oRS',;
NewObject("ADODB.Recordset"))
*-- We磍l set the Connection String for the Connection object,
*-- as we磖e quite used to.
This.oConn.ConnectionString = ;
"Provider=SQLOLEDB.1;"+;
"Initial Catalog=Northwind; Data Source=lassalanotebook;uid=sa;pwd=;"
*-- ...and open the connection.
This.oConn.Open()
*-- Let磗 set this newly created connection as the Active Connection
*-- for our RecordSet object.
This.oRS.ActiveConnection = This.oConn
*-- ...and set the RecordSet as the data source for this Cursor Adapter.
This.DataSource = This.oRS
*-- This is our command to bring our data.
This.SelectCmd = ;
"select customerid, companyname, contactname, "+;
"contacttitle, address, city, country from customers"
*-- And fill up our Cursor with data, big boy!
This.CursorFill()
EndProc
EndDefine