《Visual Foxpro 软件开发模式与应用案例》之重大错误

原创 2006年06月13日 15:32:00
 
 本人在网上听说过张老师写有关VFP的书非常好,于是慕名买了一本《Visual Foxpro 软件开发模式与应用案例》,昨晚抽了一些时间看了点,无意间发现了该书的例程代码中的“SET DELETED ON/OFF”命令使用不当,这一错误使系统留下严重的隐患。
书中第18页:
IF NOT DBUSED("dbMain")        &&打开数据库
    OPEN DATABASE dbMain EXCLUSIVE
ENDIF
SET DATABASE TO dbMain
IF NOT USED("tblOperator")     &&打开操作员表
    USE tblOperator ALIAS tblOperator IN 0
ENDIF
SELECT tblOperator
SET DELETED ON
IF NOT USED("tblDepartment")    &&打开部门表
    USE tblDepartment ALIAS tblDepartment IN 0
ENDIF
SELECT tblDepartment
SET DELETED ON
IF NOT USED("tblFormula")      &&打开公式表
    USE tblFormula ALIAS tblFormula IN 0
ENDIF
SELECT tblFormula
SET DELETED ON
IF NOT USED("tblPerson")        &&打开员工表
    USE tblPerson ALIAS tblPerson IN 0
ENDIF
SELECT tblPerson
SET DELETED ON
IF NOT USED("tblSalaryItem")    &&打开工资项目表
    USE tblSalaryItem ALIAS tblSalaryItem IN 0
ENDIF
SELECT tblSalaryItem
SET DELETED ON
SET ORDER TO fldSort
IF NOT USED("tblTally")         &&打开账套名称表
    USE tblTally ALIAS tblTally IN 0
ENDIF
SELECT tblTally
SET DELETED ON
IF NOT USED("tblBank")
    USE tblBank ALIAS tblBank IN 0
ENDIF
SELECT tblBank
SET DELETED ON
 
还第109页的代码中,作者对每一个表都分别执行了“SET DELETED ON”,虽然在这两处的代码中多次执行这一命是不会对运行结果是不会有影响的,但令我感到作者这个命令的理解产生了怀疑。“SET DELETED ON | OFF”是决定使用范围子句处理记录(包括在相关表中的记录)的命令是否忽略标有删除标记的记录。SET DELETED 的作用域是当前数据工作期。从以上代码可以看出对作者把SET DELETED 的作用域看成了是当前工作区,所以在每一个表的工作都使用了“SET DELETE ON”。虽然在这里是不会对当前运行有影响,但在一定的情况下对该命令使用不当会发生问题。
 
在第141页代码证实了我对作者的怀疑是对的。
SELECT tblStock
*!* 因为在更新tblStock表时,要依据表中当前现存的药品数量加上新开单的药品数量
*!* 或修改单的药品变动数量来计算最新库存数量,所以锁定整个表,防止其他用户同
*!* 时根据相同的库存数量计算,而不是依据最新的库存数量。
WAIT WINDOW "尝试锁定表... 按Esc键取消!" NOWAIT
IF NOT FLOCK()  
    WAIT WINDOW "表锁定失败,当前进货单未能保存,请稍后再试!" TIMEOUT 5
    ROLLBACK
    RETURN .F.
ELSE      &&锁定成功
    SELECT curIn
    SET DELETED OFF    &&处理已经删除的记录,对于这些数据要从tblStock中减去
    SCAN
       *!* OLDVAL()为空表示是新增加记录,否则为更新记录SELECT INTO CURSOR
        nOldIn_Num=IIF(ISNULL(OLDVAL("In_Num"))=.T.,0,OLDVAL("In_Num"))
        lIsDeleted=.F.
        *!* 判断删除的是否是已经保存过的记录,如果是则要从tblStock表中减去
        IF DELETED() AND ISNULL(OLDVAL("Product"))=.F.
            lIsDeleted=.T.
        ENDIF
       
        SELECT tblStock
        LOCATE FOR ALLTRIM(tblStock.Product)==ALLTRIM(curIn.Product)
        *!* 如果找到记录,表示该药品已经存在于库存中,所以实际库存应该是当前库存+当前单子中药品的数量。
        IF FOUND()   
            nCurProductNum=IIF(ISNULL(CURVAL("ProductNum"))=.T.,ProductNum,CURVAL("ProductNum"))
            IF lIsDeleted=.T.
                REPLACE tblStock.ProductNum WITH nCurProductNum-nOldIn_Num
            ELSE
                *!* 保存临时表数据时,如果数据已经保存过,则表中的最新值和OLDVAL( )函数的返回值将相同,
                *!* 使用curIn.In_Num-nOldIn_Num,这样可以防止在用户再按下保存按钮时不至于在tblStock中
                *!* 重复增加(保存)数据
                REPLACE tblStock.ProductNum WITH nCurProductNum+(curIn.In_Num-nOldIn_Num)
            ENDIF
        ELSE     &&没有找到,则追加当前药品到tblStock表中
            IF lIsDeleted=.F.
                INSERT INTO tblStock (Product,ProductNum) VALUES ;
                    (curIn.Product,curIn.In_Num)
            ENDIF
        ENDIF
        SELECT curIn
   ENDSCAN
ENDIF
 
代码中在“curIn”的工作区中执行了“SET DELETED OFF”,如果这个命令只对“curIn”的工作区起作用那是没错的,可是,这个命令对整个当前数据工作期都起作用,还会影响到在“tblStock”工作区里也没忽略做了删除标记的记录,当“tblStock”里有做了删除标记和没做删除标记的两条记录的“Product”字段值相同,且有删除标记的记录的存储顺序在前面的,接下来的“LOCATE”会定位到有删除标记的那条记录,那下面的操作就会使用数据产生混乱了。书中例程是很容易出现这种情况的,首先,例程中本来没有控制产品的名称重名,更不可能有控制不管有没有删除标记的记录是否有重名。其次,系统开始使用时必须设置商品,很容易会把一个商品加了上去,又删除了,再加回上去,最后定案使用。
 
   写于2006.6.2

Visual FoxPro 软件开发模式与应用案例

  • 2013年06月05日 14:02
  • 77.69MB
  • 下载

Visual FoxPro 6.0~9.0解决方案与范例大全写作原稿及光盘下载

自从微软宣布停止开发Visual FoxPro之后,此类图书的出版也成了难题,但是至今仍有许多VFP的坚守者,到处搜罗这本8年前的图书。特此奉上写作原稿,看起来会比淘宝上的扫描版本会舒服很多。下载地址...
  • zhanghongju
  • zhanghongju
  • 2014年11月11日 22:20
  • 4445

Visual FoxPro9.0构建管理系统图解

开发者网络 > 开发工具 > 开发专栏 > VFP > 正文   Visual FoxPro是一个有着广泛用户基础的著名数据库管理系统软件。过去,人们传说自6.0版本以后不会再发行新的版本了,可微软公...
  • ark1111
  • ark1111
  • 2005年03月02日 11:19
  • 1142

Visual Foxpro 6.0教程

下载地址:网盘下载          本书从培养应用型、技能型人才的角度出发,系统地介绍了Visual FoxPro 6.0数据库系统的基础理论及应用系统及应用系统开发知识。全书共11章,其中第1章-...
  • cf406061841
  • cf406061841
  • 2017年08月31日 01:13
  • 216

Visual foxpro 命令大全和函数大全

Visual foxpro 命令大全和函数大全 ? 在下一行显示表达式串 ?? 在当前行显示表达式串 @... 将数据按用户设定的格式显示在屏幕上或在打印机上打印 ACCEPT 把一个字符...
  • mrwu9902
  • mrwu9902
  • 2010年03月17日 15:25
  • 2779

Visual FoxPro数据库加密算法的研究与实现

摘  要:对于最初给定的随机种子,随机函数都会生成一个相同的数列。数据库数据随机加密,是一种利用随机函数的随机数序列与数据库数据进行异或等运算、实现数据库数据加密的方法。本文对数据库数据随机加密算法进...
  • feiyafei2008
  • feiyafei2008
  • 2010年05月25日 15:22
  • 1012

历史上的重大软件BUG启示录 第4篇---Google的疏忽

(图片来源于网络) 很多的软件Bug源自于输入错误,即便像Google这样的国际大公司。 在Google上搜索的时候,有些结果列表项中带有一条警告,表明Google认为它带有恶意代码。 如果你在200...
  • zhzht19861011
  • zhzht19861011
  • 2016年09月04日 11:49
  • 2098

Visual FoxPRO 更新两表的语句

因工作需要,需使用VF对两表更新其中某(几)个字段中的数据,很久没用了,经测试成功,语句如下:select 1use 2008gzzk.067inde on l2 to aselect 2use bo...
  • _NET2004
  • _NET2004
  • 2008年12月25日 14:06
  • 2188

5.如何处理“不能退出FoxPro”的情况

5如何处理“不能退出FoxPro”的情况难度系数 êêê人气指数 90%问题详述为什么在程序连编后,单击Visual FoxPro的主窗口关闭按钮,提示“不能退出FoxPro”呢?专家解答由于在Vis...
  • zhanghongju
  • zhanghongju
  • 2009年07月14日 19:40
  • 4224

C#数据库连接字符串——Visual FoxPro

ODBC DSN ODBC without DSN -- Database container (dbc) ODBC without DSN -- Free table directory OleDb...
  • mymhj
  • mymhj
  • 2010年05月07日 14:33
  • 1103
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《Visual Foxpro 软件开发模式与应用案例》之重大错误
举报原因:
原因补充:

(最多只允许输入30个字)