Access 2007的moveNext / moveFirst /等功能如何运作?

时间:2010-04-26 20:42:22

标签: sql ms-access vba

我不是Access专家,但我是SQL专家。我继承了一个Access前端,引用了一个SQL 2005数据库,该数据库可以运行大约5000条记录,但是对于800k记录来说却是惨不忍睹......

SQL Profiler&活动管理器我看到某种Access查询,如:

选择“MS1”。“id”FROM“dbo”。“customer”“MS1”ORDER BY“MS1”。“id”

MS前缀未出现在我能看到的任何访问代码中。我怀疑内置的Access导航代码:

DoCmd.GoToRecord , , acNext

GoToRecord有AcRecord常量,包括acFirst,acLast,acNext,acPrevious和acGoTo等。

在数据库环境中移动到“下一个”记录意味着什么?这个特殊的表使用一个标识列作为PK,所以它内部抓取所有 ID,然后移动到下一个最高的那个???

如果是这样,如果一个表由PK组成三个不同的字段,它会如何工作?

或者我是否在错误的轨道上,Access中的其他内容正在调用该语句?不幸的是,我在分析器中看到了大量准备好的陈述。

谢谢!

2 个答案:

答案 0 :(得分:2)

First实际上是Recordset中的第一行。通常,Access通过等效的游标访问数据。因此,NextPrevious一次一行地在Recordset中向前和向后移动,就像使用SQL Server的游标一样。注意在Recordset的构造中没有ORDER BY语句的行的顺序。虽然Access是一个ISAM,但您不应该依赖任何特定顺序的行。根据游标类型,Access不会将整个表拉下来,但通常会一次请求一条记录。也就是说,我已经看到Access出于任何原因拉出整个表格。

答案 1 :(得分:2)

您必须区分自动化Access对象和在代码中使用记录集。

在表单中,此命令具有以下含义:

  DoCmd.GoToRecord , , acNext

它是非特定的,除非您知道表单中的基础记录集和起始记录的顺序,否则它无法预测它将会记录什么记录。它会导航您通过存储在表单编辑缓冲区中的记录集(在表单的OnOpen事件中加载)。例如,该命令将用在命令按钮后面的代码中,该命令按钮的目的是导航加载到当前具有焦点的表单中的记录。如果我要使用该命令(我几乎从不这样做),我永远不会遗漏可选参数。相反,我会确定我希望它应用于的具体形式:

  DoCmd.GoToRecord acForm, "MyForm", acNext

在遍历DAO记录集时,.MoveNext同样没有预定义,除非您知道排序和开始记录。当你走一个记录集时(你不应该经常这样做,因为它效率很低;但这取决于你需要执行的任务)并且需要点击每个记录,你肯定会将.MoveNext称为你的一部分。循环:

  With rs
    .MoveFirst ' technically not required, as it's the default starting point
    Do Until .EOF
      [do something]
      .MoveNext     
    Loop
  End With

那里没什么神秘的。它最有可能用于具有少量记录的代码中(大型记录集实际上不应该按顺序导航)。

回答您的具体问题:

  

在数据库中意味着什么   上下文转移到“下一个”记录?   此特定表使用标识   列为PK,内部也是如此   抓住所有的ID,然后移动   到了下一个最高的那个???

...正如我所说,下一条记录取决于所遍历的记录集的排序和起始位置。在表单的情况下,它是正在遍历的编辑缓冲区,并且当编辑缓冲区中的当前记录书签更改时,表单将更新以加载该记录的数据。动态集绑定到基础数据表,当保存表单的编辑缓冲区时,编辑的数据将写回服务器。在进行编辑时,服务器上的记录可能会或可能不会保留锁定,但Access / Jet / ACE会跟踪服务器上现有记录的状态和编辑缓冲区中的记录,并通知您如果服务器上的记录已加载到表单的编辑缓冲区中,则可以在Access中节省时间。

现在,在评论中,您说表单绑定到整个表。无论您的数据是存储在Jet / ACE后端数据文件中还是存储在SQL Server等服务器数据库中,这都是一种糟糕的设计。 Access可以逃脱的唯一原因是因为它和Jet在从数据源中提取数据方面非常有效。

我正确设计的客户端/服务器访问前端不会在表单中加载完整的表,而是询问您要加载的过滤记录集,一次加载1个或多个记录。这只比绑定整个表格稍微复杂一点。

至于知道使用什么游标类型,你不应该担心它。默认情况下,Access表单使用Access / Jet / ACE调用动态集的内容。每个表单都有一个RecordsetType属性,默认情况下它设置为动态集(根据不同记录集类型的含义读取帮助文件)。如果您想要更多地控制它,您可以(但可能不应该)在代码中创建记录集并将它们分配给表单的.Recordset属性。这在一些情况下很有用,例如当您想要将表单绑定到断开连接的记录集时,但Access的角度是利用其处理绑定数据的功能。分配您自己的记录集仍然可以获得绑定控件和表单事件,但是通常需要的工作量更多。

基本上,将表单更改为仅加载用户需要使用的记录子集(可能一次只能记录一条记录),然后让其他所有内容完成Access的默认行为。如果某些事情导致瓶颈,那么对其进行故障排除并用更有效的方法替换默认行为。

换句话说,避免过早优化 - 让Access成为Access。

并且不要担心Access在幕后做什么,除非/直到Access做了不适当的事情。