参数化命令的操作
如果使用的是大型子 Recordset(尤其是与父 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 子句引用该内容(即“...PARAMETER 0”)。
注意
PARAMETER 子句仅与 shape 命令语法相关。 它不与 ADO Parameter 对象或 Parameters 集合相关联。
执行参数化 shape 命令时,将发生以下情况:
将会执行父命令并从 Customers 表中返回父 Recordset。
段列将追加到父 Recordset 中。
访问父行的段列时,将使用 customer.cust_id 的值作为参数的值执行子命令。
步骤 3 中创建的数据提供程序行集内的所有行都用于填充子 Recordset。 在此示例中,这就是 Orders 表中 cust_id 等于 customer.cust_id 值的所有行。 默认情况下,子 Recordset 将缓存在客户端上,直到对父 Recordset 的所有引用都释放。 若要更改此行为,请将 Recordset 的动态属性“缓存子行”设置为 False。
对检索到的子行(即子 Recordset 的段)的引用放置在父 Recordset 的当前行的段列中。
访问另一行的段列时,将重复步骤 3-5。
默认情况下,“缓存子行”动态属性设置为 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.
在具有两个或多个参数的查询中,仅当所有参数值与缓存的值匹配时,才会使用缓存的子级。
参数化命令和复杂的父子关系
除了使用参数化命令来提高同等联接类型层次结构的性能之外,参数化命令还可用于支持更复杂的父子关系。 例如,考虑一个包含两个表的 Little League 数据库:一个由团队信息(team_id、team_name)组成,另一个由比赛信息(date、home_team、vising_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 子句强大的灵活性来获取所需的结果。
注意
使用 WHERE 子句时,参数不能将 SQL 数据类型用于 text、ntext 和 image,否则会出现一条错误,其中包含以下说明:Invalid operator for data type
。