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



FoxPro7

注意:单词";记录集";可能不正确,但我真的不明白它们是如何工作的。我是SQL专家,所以我正在努力翻译。这是风景吗?它是数据的副本吗?我不知道。

问题:

  1. 如果您正在使用2个记录集并进行更改,更改是否显示在1个记录集中?也许他们都指向同一个记录集
  2. IF FOUND怎么可能是假的?该代码将表的子集与完整表进行比较。这应该永远是真的
  3. DO WHILE是否受到打滑的影响?一旦你开始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. 如果筛选的表中有数据,则FOUND()永远不会为false(选择2)。它不一定总是是真的,因为有可能在过滤的文件中没有数据,在这种情况下;如果Found()"代码不会被调用
  3. DO WHILE受SKIP影响:过滤后的表(选择2)向前移动,每个循环1条记录。例如,如果#1总共有20条记录,而#2(已筛选)有4条记录,则您发布的代码将循环到#2(第1、第2、第3、第4)。为#2中的4条记录中的每一条创建变量,并在#1中通过查找(SEEK())记录进行更新

在解释了所有这些之后,通过删除所有记录(CLASS_CODE='5156')并打包它们,看起来对表的所有更新在最后都被完全删除了。CLASS_CODE将永远不会基于此代码段设置为"5157"。这没有道理。这篇文章写得不好。它所要做的似乎只是删除CLASS_CODE='5156'的记录。

Ed已经很好地解释了IMHO。让我添加\扩展更多:

  1. 记录集是一个宽泛的术语,它可能意味着作为一组记录的任何东西(无论是表、视图、表值函数、游标…),就像在SQL中一样

选择1并选择2平均值;工作区域";1和2。您可能认为这些数字是唯一的连接句柄。您可以使用关键字"在多个工作区域中打开同一个表\视图(或光标…);再次";。第一个使用与表名相同的别名(比方说表——很可能是一个表)。第二个是由VFP支配,并分配了一个自动别名。别名只是SQL中的本地别名。

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

  1. 你可能完全正确。然而,使用现有的代码,它甚至无法工作并导致错误。如果你真的有这个代码并且它正在运行,那么前面有一些代码可以消除错误。此代码实际发生的情况是:

它在SEEK上出错。。。线我相信前面的一些代码会使错误静音由于静音,FOUND()始终为FALSE,当前过滤的数据被替换为"5157",并跳到下一条记录。

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

agency_code + index_no + class_code

更糟糕的是,此代码中的数据类型未知,这些变量以"n"all为前缀,这可能意味着它们是数字,那么这将是3个数字字段的总和,而不是3个字符字段的串联。即:

agency_code=1index_no=1class_code=1

然后这个搜索就意味着:

SEEK 3

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

Do While只关心它的逻辑表达式部分。在这个代码中,它只是检查它是否是EOF()。EOF()的意思是"文件结束";"当前表\视图\光标";。由于只是在ENDDO之前点击,它正在执行SELECT 2,这意味着循环将继续,直到在工作区域2中点击EOF(通过CLASS_CODE='5156'过滤)。由于代码中没有其他内容可以移动任何表中的指针,因此它是工作区2中记录的一次传递(就SQL server而言,您使用CLASS_code="5156"声明一个用于select的游标,fetch next直到状态不是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中这样写)。

最新更新