Welcome

首页 / 软件开发 / VFP / 用vfp与sql server构建Client/Server应用程序(远程视图)(5)

用vfp与sql server构建Client/Server应用程序(远程视图)(5)2007-05-09刷新缓冲(refreshing buffers)

记得在“以缓冲理解更新冲突”一节中我们提到过什么情况下Visual FoxPro会刷新缓冲区。其中“远程视图光标被打开”是很好的理解,这里不再累述。

以 REQUERY()函数刷新远程视图光标

REQUERY()函数的作用就是重新执行远程视图的SELECT-SQL描述,也就是重新打开远程视图光标,所以对系统造成较大的负担。对于这个函数,我有几点建议:

  1. 执行成功,返回:1;反之,函数返回:0。

  2. 执行成功,记录指针将停在首记录,因为本函数就如同重新打开远程视图。

  3. 由于是重新下载数据,本函数对缓冲进行全部刷新。

  4. 行缓冲下,如果修改了一行记录,但未发送更新时,使用本函数,Visual FoxPro将先发送更新,如果没有更新冲突,才重新下载数据光标;如果发生更新冲突,本函数不被执行,返回 0。

  5. 表缓冲下,如果修改了任何记录,但没有发送更新,本函数将不被执行,出现如图11的提示,返回0。


图 11。 表缓冲下更新没有被确认,不能使用REQUERY()函数

发送更新成功,只刷新被更新记录的相关字段的缓冲

也许这个标题很难理解,那么我们就分析一下:

  1. 无论是行缓冲还是表缓冲模式,发送更新成功,Visual FoxPro将已更新字段的新值填入缓冲。也就是说,没有被更新字段的缓冲区不被刷新。

  2. 行缓冲下发送更新成功,只刷新当前记录地被更新字段的缓冲。

  3. 表缓冲下发送更新成功,只刷新被更新的若干记录的各自被更新字段的缓冲。

我认为,Visual FoxPro所谓刷新缓冲,只不过是Visual FoxPro自己的行为而与远程数据源无关,也就是由Visual FoxPro生成UPDATE-SQL语句时,Visual FoxPro自动将新值填入缓冲,Visual FoxPro再发送此SQL描述。所以被刷新的就是被更新的字段的缓冲,并且无论更新是否成功!

远程视图的其他属性

远程视图的高级属性可以通过可视工具设定,下面我们就讲解一下:

FetchASNeed 和 FetchSize 即:取得远端所需的数据和每次提取的记录数

这两个属性是成对工作的,默认设定是:

DBSETPROP("ViewName","View","FetchSize",100)
DBSETPROP("ViewName","View","FetchAsNeed",.F.)

表示远程视图打开时,每批下载100条记录,当第一批100条记录被下载完毕后,Visual FoxPro将把控制权还给用户或继续往下执行程序。这样就有问题了:如果几个远程视图共享一条连接,接可能造成连接堵塞。如下:

CREATE SQL VIEW VOrders ;
REMOTE CONNECTION Northwind SHARE;
AS SELECT * FROM Orders
CREATE SQL VIEW VCustomers ;
REMOTE CONNECTION Northwind SHARE;
AS SELECT * FROM Customers
*在命令窗口同时选中以下命令,按回车键
Use VOrders in 0
Use VCustomers in 0
*弹出“连接 Northwind忙" 的提示窗口

让我们分析原因:当VOrder的一批100条记录被下载完毕后,Visual FoxPro就执行打开VCustomers表的命令,这时对于连接Northwind将面临两项任务:继续下载VOrder的第二批100条记录、下载VCustomers的第一批记录,一个连接无法同时应付两项任务,所以“连接忙”。

解决以上问题,可以这样设置:

DBSETPROP("VOrders","View","FetchSize",-1)
*表示一次下载所有记录,完成此任务才将控制权交回或继续执行程序。

如果你这样设置:

DBSETPROP("VOrders","View","FetchSize",100)
DBSETPROP("VOrders","View","FetchAsNeed",.T.)

USE VOrders
*下在100条记录,并将控制权交还用户,由于FetchAsNeed=.T.,不像刚才——Visual FoxPro自动控制继续下载数据,连接被霸占
go 100
*第100条记录已经下载,所以VOrders不下载任何数据,连接被霸占
go 105
*第105条记录还没有下载到客户端,所以VOrder下载5条数据以满足用户的需要,连接被霸占
go bottom
*下载所有记录,连接被释放

MaxRecords 即:要提取的最大记录数

这个属性是指远程视图光标最多可以下载的记录数,并且它的优先级比上两个属性高。也就是说无论上两个属性怎样设置,客户端就只能拥有小于等于MaxRecords条从远端下载的记录,并且达到这个数量后,“霸占”连接就被释放、可以供其它视图使用。这个属性可以这样设定:

DBSETPROP("ViewName", "View", "MaxRecords", 25)

FetchMemo 即:取备注字段

如果远程视图中包含备注字段,一般认为:一次性下载这些数据到客户端是很没有意义的、也是没有效率的,而且猛增了网络流量。比较好的做法是:用的时候才下载。所谓用的时候就是指:明显或隐含的Modi Memo命令。可以这样设置它的属性:

DBSETPROP("ViewName", "view", "FetchMemo", .F.)

CompareMemo 即:在 Where 子句中包含备注字段

当远程视图包含备注字段或是通用字段时,这个属性非常重要的。这个属性的默认值是.T.,即在检测更新冲突时把这两种字段与其它类型的字段同等看待。笔者认为,这种设置有一个不合理、一个错误,请听我道来:

先说错误,当一个通用型(不包括“备注型字段”)字段被设定为可更新,并使用了“关键字与可更新字段”或“关键字与已更新字段”的更新冲突检测方式,Visual FoxPro 不允许这种设定。在视图设计阶段,Visual FoxPro 不会指出这个错误,但当实际发送 UPDATE-SQL 时会出现错误提示。

在讲“不合理”。我刚才指出,备注字段是可以参与更新冲突检测的,但是这样对服务器的压力很大、对网络的压力也很大。

所以一般应用中,我们会把该值设定为 .F.,即当更新冲突检测方式为“关键字与可更新字段”或“关键字与已更新字段”的时候,即使有关备注字段或通用型字段客户端程序被更改,Visual FoxPro 发送 UPDATE-SQL 会把这两类字段从 Where 子句中挖去。这样可以避免以上我提出的“一个错误、一个不合理”。

可以这样设定:

DBSetProp("VEMPLOYEES", "View", "CompareMemo", .F.)

字段属性

DefaultValue

如果您希望对远程视图执行Append命令时,系统自动填列有关字段,那么就有必要设定该属性:

DBSETPROP("myview.myfield", "field", "DefaultValue", ".T. ")
DBSETPROP("myview.myfield", "field", "DefaultValue", ""Bob"")
DBSETPROP("myview.myfield", "field", "DefaultValue", Date())

DataType

以下是Visual FoxPro字段类型与SQL Server字段类型的比较:

SQL typeVisual FoxPro type
binary, varbinaryMemo
bitLogical
char, varcharCharacter
datetime, smalldatetimeDatetime
decimalNumeric
floatDouble
imageGeneral
int, smallint, tinyintInteger
money, smallmoneyCurrency
numericNumeric
sysnameCharacter
textMemo
timestampMemo
您可以这样设置:

DBSETPROP("Vemployees.birthdate", "field", "DataType", "D")

UpdateName

这个属性在多表连接是很重要,在多个表中许多列可能有相同的名称,所以必须明确的告诉远程视图,视图中的列与数据源表的列的对应关系。如:

DBSETPROP("VCustomers.postalcode", "field", "UpdateName", "customers.postalcode")