技术开发 频道

在SQL Server2005中实现数组映射(一)



三、在SQL中的聚合映射


   
也许我们会有这样的疑问,SP_map对大的列表的处理分怎么样呢。对于上面的例子,假设我们提供了一个包含100个元素的列表。SP_map为每一个被执行的表达式返回一个结果集(也就是对每一个输入元素)。因此,会有很多可滚动的窗口。那么对于数据更多的列表,SP_map提供了一个@Accumulate标志,来将众多小的结果集合成一个。虽然从概念上非常简单,但所不同的是SP_map所做的主要功能将发生改变。这将重写我们的查询代码。在其中将一个新的包含输入元素的列。否则,我们将没有办法将输入和输出相连,如图4所示:  
   
打开@Accumulate标志后,将利用我们的SELECT表达式上的一个约束(就是所有被返回的字段必须被命名)。换句话说,'select count(*) from <MAIN_ARG>'将不再有效,而我们将使用'select count(*) as Count from <MAIN_ARG>'来取代原来的语句,如图4所示:



图4 聚合映射:打开@Accumulate标志后,将合并多个结果集为一个更便利的结果集

    如果我们忘记了,SQL Server将会出现一个类似下面的错误:   

An object or column name is missing or empty.
   For SELECT INTO statements, verify each column
   has a name. For other statements, look for
   empty alias names.
   Aliases defined as "" or [] are not allowed.
   Add a name or single space as the alias name.

   
我们可以通过设置@Verbose标志来查看代码。代码如下所示:
SELECT Convert(varchar(128),'Person.Address') as ItemName, count(*) as Rows INTO #Map_Temp_Table from Person.Address INSERT INTO #Map_Temp_Table SELECT 'Person.Contact', count(*) as Rows from Person.Contact INSERT INTO #Map_Temp_Table SELECT 'Production.Culture', count(*) as Rows from Production.Culture INSERT INTO #Map_Temp_Table SELECT 'Sales.Customer', count(*) as Rows from Sales.Customer select * from #Map_Temp_Table drop table #Map_Temp_Table


我们从上面的代码可以看到,SP_map使用了一个中间临时表秋收集独立的结果集。如果我们将verbosity标志从1设置到2,我们会看到更多更清晰的代码(这将显示除了实际执行的代码块外的中间CREATE和UPDATE模板)。SP_map直接从我们的表达式模板产生这些中间模板,然后使用这些中间模板从输入列表中映射数据。CREATE和UPDATE模板的代码如下:

   -- TEMPLATE (create):
       SELECT Convert(varchar(128),
         '<MAIN_ARG>') as ItemName, count(*) as Rows
       INTO #Map_Temp_Table from <MAIN_ARG>
   -- TEMPLATE (update):
       INSERT INTO #Map_Temp_Table
       SELECT '<MAIN_ARG>', count(*) as Rows from <MAIN_ARG>
 

对于我们的输入列表的第一个元素,SP_map使用了CREATE模板动态地定义了一个临时表,并存储第一个结果集。对于后面的部分使用了UPDATE模板来向临时表追加行。当完成时,使用一条SELECT语句从临时表中查出所有的数据。并生成一个单独的结果集,最后删除临时表。

0
相关文章