参数化命令的操作

如果使用的是大型子 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 命令时,将发生以下情况:

  1. 将会执行父命令并从 Customers 表中返回父 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。

默认情况下,“缓存子行”动态属性设置为 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

另请参阅

数据整理示例
正式 Shape 语法
常用 Shape 命令