为什么这个IF FOUND有一个始终为真的条件?

问题描述

FoxPro7

注意:“记录集”一词可能不正确,但我真的不明白它们是如何工作的。我是一名sql专家,所以我正在尝试翻译。是风景吗?它是数据的副本吗?我不知道。

问题:

  1. 如果您使用2个记录集并进行更改,更改是否会显示在1个记录集中?也许他们都指向同一个记录集?
  2. 如果找到的话怎么可能是假的?该代码将表的子集与整个表进行比较。应该永远是真的。
  3. WHILE是否受到SKIP的影响?很难在开始do while后就确定记录集是否固定,或者是否会破坏循环中的记录。如果您更改行,我不会掌握记录循环中“您在哪里”与“您所指向的东西”之间的区别。

谢谢!

    Select 1
    Use tblincls    
    
    Select 2
    Use tblincls Again
    Set Filter To CLASS_CODE = '5156'
    Goto Top

    do while Not Eof()
    
    nagency_code = agency_code
    nindex_no = index_no
    nclass_code = CLASS_CODE
    npys_exp = pys_exp
    namt_exp = amt_exp

    Select 1
    Seek nagency_code + nindex_no + nclass_code
    If Found()
        Replace pys_exp With (pys_exp + npys_exp)
        Select 2
    Else
        Select 2
        Replace CLASS_CODE With '5157'
    Endif
    Select 2
    Skip
    Enddo

    Close Tables All
    Use tblincls Excl
    Delete All For CLASS_CODE = '5156'
    Pack
    Close Tables All

解决方法

注意:“记录集”一词可能不正确,但我确实不正确 了解他们的工作方式。我是一名SQL专家,所以我正在尝试翻译。是 它的看法?它是数据的副本吗?我不知道。

基于代码示例,“记录集”很可能是VFP表(但可能是视图),该表是VFP数据库容器(dbc)的一部分。我知道这是因为有一个字段名超过10个字符:一个空闲表只能有10个字符;超过10个字符将要求表/视图位于dbc中。我将使用“表格”回答您的问题。

答案:

  1. tblincls表被打开两次。对表所做的任何更改都将反映在两个选择区域(1和2)中。就像2个用户打开一个共享文件一样。两者都在同一个数据文件上工作。
  2. 如果过滤的表中有数据(选择2),则
  3. FOUND()永远不会为假。不一定总是正确的,因为在这种情况下,筛选出的文件中可能没有数据,因此不会调用“ If Found()”代码。li>
  4. DO WHILE受SKIP的影响:已过滤的表(选择2)向前移动1个记录,每个循环。例如,如果#1总共有20条记录,而#2(已过滤)有4条记录,则您发布的代码将遍历#2(第一,第二,第三,第四)。为#2中的4条记录中的每条记录创建变量,并通过在#1中找到(SEEK())记录在#1中进行更新。

解释了所有这一切之后,似乎通过删除所有记录(CLASS_CODE ='5156')并将它们打包,最终消除了对该表所做的所有更新。根据此代码段,CLASS_CODE永远不会设置为“ 5157”。这没有道理。这写得不好。似乎要做的就是删除CLASS_CODE ='5156'的记录。

,

爱德华已经很好地解释了恕我直言。让我添加\展开更多:

  1. 记录集是一个广义的术语,它可能表示一组记录(包括表,视图,表值函数,游标...)的任何内容-就像在SQL中一样。

选择1并选择2表示平均值,然后选择“工作区域” 1和2。您可能会认为这些数字是唯一的连接句柄。您可以使用关键字“ AGAIN”在多个工作区域中打开相同的表格\视图(或光标...)。第一个使用与表名相同的别名(比方说table-很可能是一个表)。第二个问题由VFP负责,并为其分配了自动别名。别名只是SQL中的本地别名。

是的,它们是2个指向同一表的连接。

  1. 您可能完全正确。但是,使用现有代码,它甚至无法工作并导致错误。如果您确实有此代码并且该代码正在运行,那么前面有一些代码可以使错误静音。这段代码真正发生的是:

在SEEK ...行上出错 我相信之前的一些代码使错误消失了 由于沉默,FOUND()始终为FALSE,当前过滤的数据将替换为“ 5157”,并跳至下一条记录。

如果SEEK不会出错,那么仍然不能保证匹配,并且FOUND()可能为false,因为: SEEK根据当前索引运行。当前索引可能与以下搜索条件不匹配:

agency_code + index_no + class_code

更糟,此代码中不知道数据类型,这些变量以'n'全部作为前缀,这可能意味着它们是数字,然后将是3个数字字段的总和,而不是3个字符字段的串联。即:

agency_code = 1 index_no = 1 class_code = 1

该搜索将意味着:

SEEK 3

但是,我们已经知道CLASS_CODE是一个字符串,其他的也应该是字符串(或者这是另一个错误)。

  1. Do While仅关心其逻辑表达式部分。在此代码中,仅检查它是否为EOF()。 EOF()表示“当前表\视图\光标”的文件末尾。由于只是在执行ENDD​​O之前命中,所以它执行SELECT 2,这意味着循环将继续进行,直到在工作区2中命中EOF(由CLASS_CODE ='5156'过滤)为止。由于代码中没有任何其他东西可以移动任何表中的指针,因此它是工作区2中记录的一遍(就SQL Server而言,您可以使用CLASS_CODE ='5156'声明要选择的游标,然后读取直到状态不是0)。

让我们对代码本身进行扩展评论:

* Select workarea 1 - like opening a new connection tab in SSMS to the same database
Select 1
* Open table tblincls in this work area
* it is like allocating a cursor but let's don't make it complex
Use tblincls


* Select workarea 2 - like opening a new connection tab in SSMS to the same database
Select 2
* Open table tblincls in this work area AGAIN with a local alias of (likely  - automatic) B
Use tblincls Again
* Filter this one 
Set Filter To CLASS_CODE = '5156'
Goto Top


* So up to this point it is as if you have 2 cursors allocated
* one with
* Select * from tblincls
* and the other
* Select * from tblincls where CLASS_CODE = '5156'


* Starting a loop using - on work area 2
Do While Not Eof()

* Copy contents of some fields to some memory vairables 
* (The variables on left are all memory variables,* because in VFP you cannot do assigment to field variables)

    nagency_code = agency_code
    nindex_no = index_no
    nclass_code = CLASS_CODE
    npys_exp = pys_exp
    namt_exp = amt_exp

* Select work area 1
    Select 1
* Call SEEK. Since there is no index set,this would cause an error
* error is likely silenced by some preceding code (or in a TRY block)
* ie: If you had a line like this,code would continue without displaying any error 
* On error x=1 
* A dummy error silencer

    Seek nagency_code + nindex_no + nclass_code

* Always FALSE because of the error

* If index was set and error didn't occur
* and also index expression matches to 
* agency_code + index_no + class_code
* at least,then that would mean always TRUE
* It would find the record itself,or some other row
* Which row it would be is unpredictable (unless that expression is unique)

    If Found()
        Replace pys_exp With (pys_exp + npys_exp)
        Select 2
    Else
        Select 2
        Replace CLASS_CODE With '5157'
    EndIf
    
* Select work area 2 regardless of the above    
    Select 2
* Move the pointer
    Skip
Enddo

* No need to explain rest I guess
Close Tables All
Use tblincls Excl
Delete All For CLASS_CODE = '5156'
Pack
Close Tables All

最重要的是,这是我见过的最糟糕的代码之一。可能我可以将其翻译为SQL(说SQL可能是任何方言):

Update tblincls Set Class_Code = '5157' where class_code = '5156'

之所以这样,是因为代码归结为这个(我也将在VFP中这样写)。