参数化命令的操作
适用于: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 命令时,将发生以下操作:
执行父命令并从“客户”表返回父 Recordset。
向父 Recordset 追加章节列。
访问父行的章节列时,将 customer.cust_id 的值用作参数值以执行该子命令。
使用在步骤 3 中创建的数据提供程序行集的所有行来填充子 Recordset 。 在此示例中,这是 Orders 表中 cust_id 等于 customer.cust_id 值的所有行。 默认情况下,子 Recordset 将缓存在客户端,直到对父 Recordset 的所有引用被释放。 若要更改此行为,请将 Recordset动态属性“缓存子行”设置为 False。
对所检索的子行的引用(即子 Recordset 的章节)将放在父 Recordset 的当前行的章节列中。
在访问另一个行的章节列时,将重复步骤 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 子句具有的更大灵活性来获得需要的结果。