《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
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《敏捷软件开发》《企业应用架构模式》读后感

《敏捷软件开发》《企业应用架构模式》都是比较老的书了,出的时候我才刚上大学吧。当年看一定比现在看的收获大。 书里说的有些已经过时,有些已成为当今的常识,有些已被常用框架实现,有些还是经典。 ...

论设计模式在软件开发中的应用

注:本文转载自:http://blog.csdn.net/yinyuan1987/article/details/3209783 感谢原作者分享 在解决这个论题之前,我们首先要了解设计模式的概...

设计模式 - 在软件开发中的应用

论设计模式在软件开发中的应用作者:jercy 时间:2008-11-2 在解决这个论题之前,我们首先要了解设计模式的概念,及其基本的分类。“设计模式”这四个字,相信大家在很多地方都会看到,什么是设计模...

论设计模式在软件开发中的应用

论设计模式在软件开发中的应用        在解决这个论题之前,我们首先要了解设计模式的概念,及其基本的分类。        “设计模式”这四个字,相信大家在很多地方都会看到,什么是设计模式呢? ...

论设计模式在软件开发中的应用

在解决这个论题之前,我们首先要了解设计模式的概念,及其基本的分类。 “设计模式”这四个字,相信大家在很多地方都会看到, 什么是设计模式呢?  一个设计模式提供一种提炼子系统或软件系统中的组件的,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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