问题描述
FoxPro7
注意:“记录集”一词可能不正确,但我真的不明白它们是如何工作的。我是一名sql专家,所以我正在尝试翻译。是风景吗?它是数据的副本吗?我不知道。
问题:
- 如果您使用2个记录集并进行更改,更改是否会显示在1个记录集中?也许他们都指向同一个记录集?
- 如果找到的话怎么可能是假的?该代码将表的子集与整个表进行比较。应该永远是真的。
- 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中。我将使用“表格”回答您的问题。
答案:
- tblincls表被打开两次。对表所做的任何更改都将反映在两个选择区域(1和2)中。就像2个用户打开一个共享文件一样。两者都在同一个数据文件上工作。 如果过滤的表中有数据(选择2),则
- FOUND()永远不会为假。不一定总是正确的,因为在这种情况下,筛选出的文件中可能没有数据,因此不会调用“ If Found()”代码。li>
- DO WHILE受SKIP的影响:已过滤的表(选择2)向前移动1个记录,每个循环。例如,如果#1总共有20条记录,而#2(已过滤)有4条记录,则您发布的代码将遍历#2(第一,第二,第三,第四)。为#2中的4条记录中的每条记录创建变量,并通过在#1中找到(SEEK())记录在#1中进行更新。
解释了所有这一切之后,似乎通过删除所有记录(CLASS_CODE ='5156')并将它们打包,最终消除了对该表所做的所有更新。根据此代码段,CLASS_CODE永远不会设置为“ 5157”。这没有道理。这写得不好。似乎要做的就是删除CLASS_CODE ='5156'的记录。
,爱德华已经很好地解释了恕我直言。让我添加\展开更多:
- 记录集是一个广义的术语,它可能表示一组记录(包括表,视图,表值函数,游标...)的任何内容-就像在SQL中一样。
选择1并选择2表示平均值,然后选择“工作区域” 1和2。您可能会认为这些数字是唯一的连接句柄。您可以使用关键字“ AGAIN”在多个工作区域中打开相同的表格\视图(或光标...)。第一个使用与表名相同的别名(比方说table-很可能是一个表)。第二个问题由VFP负责,并为其分配了自动别名。别名只是SQL中的本地别名。
是的,它们是2个指向同一表的连接。
- 您可能完全正确。但是,使用现有代码,它甚至无法工作并导致错误。如果您确实有此代码并且该代码正在运行,那么前面有一些代码可以使错误静音。这段代码真正发生的是:
在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是一个字符串,其他的也应该是字符串(或者这是另一个错误)。
- Do While仅关心其逻辑表达式部分。在此代码中,仅检查它是否为EOF()。 EOF()表示“当前表\视图\光标”的文件末尾。由于只是在执行ENDDO之前命中,所以它执行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中这样写)。