参数化命令的操作
如果使用大型子 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 集合不关联。
执行参数化形状命令时,将发生以下情况:
执行父命令 ,并从 Customers 表中返回父记录集 。
将章节栏目追加到父 记录集。
访问父行的章节列时,将使用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.
在具有两个或多个参数的查询中,仅当所有参数值与缓存的值匹配时,才会使用缓存的子级。
参数化命令和复杂的父子关系
除了使用参数化命令来提高等式联接类型层次结构的性能之外,参数化命令还可用于支持更复杂的父子关系。 例如,考虑一个包含两个表的小联盟数据库:一个由球队(team_id、team_name)组成,另一个由比赛(日期、home_team、visiting_team)组成。
使用非参数化层次结构时,无法将团队表和比赛表关联,以使每个团队的子 Recordset 包含其完整的赛程安排。 可以创建包含家庭计划或道路日程的章节,但不能同时创建这两个章节。 这是因为 RELATE 子句将你限制为格式(pc1=cc1)和(pc2=pc2)的父子关系。 因此,如果你的命令包括“将team_id关联到home_team,team_id关联到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 子句时,参数不能对文本、ntext 和 image 使用 SQL 数据类型,否则将产生包含以下说明的错误:Invalid operator for data type
。