当前位置: 首页 > 编程语言 > vfp > 正文

用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 type Visual FoxPro type
binary, varbinary Memo
bit Logical
char, varchar Character
datetime, smalldatetime Datetime
decimal Numeric
float Double
image General
int, smallint, tinyint Integer
money, smallmoney Currency
numeric Numeric
sysname Character
text Memo
timestamp Memo

您可以这样设置:

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

UpdateName

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

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