参数化命令的操作

适用于:Access 2013、Office 2013

如果要使用大型子 Recordset(尤其是与父 Recordset 的大小相比较),但只需要访问少量子章节,则可能发现使用参数化命令会更有效。

非参数化命令会同时检索整个父和子 Recordset,然后向该父对象追加章节列,最后分配对每个父行的相关子章节的引用。

参数化命令会检索整个父 Recordset,但只有在访问章节列时才会检索章节 Recordset。 此检索策略差异可以产生极大的性能收益。

例如,可以指定以下内容:

 
SHAPE {SELECT * FROM customer} 
 APPEND ({SELECT * FROM orders WHERE cust_id = ?} 
 RELATE cust_id TO PARAMETER 0) 

父表和子表有一个共同的列名,cust_id*。* 子命令 具有一个“?”占位符,RELATE 子句引用该占位符 (即“...参数 0“) 。

注意

[!注释] PARAMETER 子句仅仅属于 Shape 命令语法。 它不与 ADO Parameter 对象或 Parameters 集合关联。

执行参数化 Shape 命令时,将发生以下操作:

  1. 执行父命令并从“客户”表返回父 Recordset

  2. 向父 Recordset 追加章节列。

  3. 访问父行的章节列时,将 customer.cust_id 的值用作参数值以执行该子命令

  4. 使用在步骤 3 中创建的数据提供程序行集的所有行来填充子 Recordset 。 在此示例中,这是 Orders 表中 cust_id 等于 customer.cust_id 值的所有行。 默认情况下,子 Recordset 将缓存在客户端,直到对父 Recordset 的所有引用被释放。 若要更改此行为,请将 Recordset动态属性缓存子行”设置为 False

  5. 对所检索的子行的引用(即子 Recordset 的章节)将放在父 Recordset 的当前行的章节列中。

  6. 在访问另一个行的章节列时,将重复步骤 3–5。

默认情况下, Cache Child Rows 动态属性设置为 True 。 缓存行为因查询的参数值而异。 在使用单个参数的查询中,在请求具有该值的子项的间隔期中,系统将缓存给定参数值的子 Recordset 。 以下代码演示了这种情况:

... 
SCmd = "SHAPE {select * from customer} " & _ 
 "APPEND({select * from orders where cust_id = ?} " & _ 
 "RELATE cust_id TO PARAMETER 0) AS chpCustOrder" 
Rst1.Open sCmd, Cnn1 
Set RstChild = Rst1("chpCustOrder").Value 
Rst1.MoveNext ' Next cust_id passed to Param 0, & new rs fetched 
 ' into RstChild. 
Rst1.MovePrevious ' RstChild now holds cached rs, saving round trip. 
... 

在具有两个或更多个参数的查询中,只有当所有参数值都与缓存值匹配时,才会使用缓存的子项。

参数化命令和复杂的父子关系

除了使用参数化命令来改进 equi-join 类型层次结构的性能以外,还可以用参数化命令来支持更复杂的父子关系。 例如,假设有一个 Little League 数据库,它有两个表:一个由团队组成(team_id、team_name),另一个由比赛组成(date、home_team、visiting_team)。

如果使用非参数化层次结构,则无法通过让团队表和比赛表相关来使每个团队的子 Recordset 都包含它已完成的赛程。 可以创建包含主场赛程或客场赛程(但不同时包含这二者)的章节。 这是因为 RELATE 子句使您只能建立形式为 (pc1=cc1) AND (pc2=pc2) 的父子关系。 因此,如果命令包括"RELATE team_id TO home_team, team_id TO visiting_team",则只能获得团队与自己比赛的结果。 而您需要的是"(team_id=home_team) OR (team_id=visiting_team)",但 Shape 提供程序不支持 OR 子句。

若要获得希望的结果,可以使用参数化命令。 例如:

 
SHAPE {SELECT * FROM teams} 
APPEND ({SELECT * FROM games WHERE home_team = ? OR visiting_team = ?} 
 RELATE team_id TO PARAMETER 0, 
 team_id TO PARAMETER 1) 

此示例利用 SQL WHERE 子句具有的更大灵活性来获得需要的结果。