技术开发 频道

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



【IT168 专稿】

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

四、重新访问聚合映射
 
    到现在为止我们已经学会了如何通过一系列参数来聚合一条简单的SELECT语句。但是这样仅仅在与如sp_who这样的存储过程联合时才有用。sp_who可以列出当前的用户,或使用sp_spaceused,这个存储过程可以返回关于表、视图或查询。行数和磁盘信息。如下面的代码使用SP_map对两个表调用了sp_spaceused:
 
   EXEC SP_map
       @StmtTemplate = "execute sp_spaceused <MAIN_ARG>",
       @MainArray    = 'Users, Permissions',
       @Accumulate   = 0
 
    我们看到的@Accumulate标志,将多个结果集合为了一个。但使用存储过程做这件事和使用简单的SELECT语句是有很大差异的。如果我们编辑上面的代码,将@Accumulate打开,并设置@Verbose为1,SP_map将返回如下的代码:

-- TEMPLATE (create): SELECT * INTO #Map_Temp_Table FROM OPENROWSET ('SQLOLEDB', 'Server=(local)\SqlExpress;TRUSTED_CONNECTION=YES;', 'set fmtonly off execute dbo.sp_spaceused <MAIN_ARG>') -- TEMPLATE (update): INSERT INTO #Map_Temp_Table SELECT * FROM OPENROWSET ('SQLOLEDB', 'Server=(local)\SqlExpress;TRUSTED_CONNECTION=YES;', 'set fmtonly off execute dbo.sp_spaceused <MAIN_ARG>') SELECT * INTO #Map_Temp_Table FROM OPENROWSET ('SQLOLEDB','Server=(local)\SqlExpress;TRUSTED_CONNECTION=YES;', 'set fmtonly off execute dbo.sp_spaceused Users') INSERT INTO #Map_Temp_Table SELECT * FROM OPENROWSET ('SQLOLEDB','Server=(local)\SqlExpress;TRUSTED_CONNECTION=YES;', 'set fmtonly off execute dbo.sp_spaceused Permissions') select * from #Map_Temp_Table drop table #Map_Temp_Table

 
 
 当按通常方法调用上面的语句时(不使用SP_map包装),存储过程将返回单独的结果集。但是一个特殊的存储过程—sp_msForEachTable-可以返回多个结果集(每一个表是一个结果集)。为了显示所有表的结果集,可以使用下面的标准调用方式,代码如下:
 
   EXEC sp_msForEachTable "EXEC sp_spaceused '?'"

   SP_map还只要在语句上稍加修改,就可以将输出结果转换为一个结果集。代码如下:
 
   EXEC SP_map
       @StmtTemplate = 'EXEC sp_msForEachTable
       "EXEC sp_spaceused ''?''"', @Accumulate = 1

    要注意的是,只有我们不用支持@MainArray作为参数时,还可以在SP_map中包装返回多个结果集的存储过程。而@MainArray,在这种情况下,已经在表名集合中被隐含定义了。上面调用SP_map后将产生如下的代码:
- TEMPLATE (create): SELECT * INTO #Map_Temp_Table FROM OPENROWSET ( 'SQLOLEDB', 'Server=(local)\SqlExpress;TRUSTED_CONNECTION=YES;', 'set fmtonly off EXEC dbo.sp_msForEachTable "select convert(varchar(128), ''?'') as Name"') TRUNCATE TABLE #Map_Temp_Table INSERT INTO #Map_Temp_Table EXEC dbo.sp_msForEachTable "select convert(varchar(128), '?') as Name" SELECT * INTO #Map_Temp_Table FROM OPENROWSET ( 'SQLOLEDB', 'Server=(local)\SqlExpress;TRUSTED_CONNECTION=YES;', 'set fmtonly off EXEC dbo.sp_msForEachTable "select convert(varchar(128), ''?'') as Name" ') TRUNCATE TABLE #Map_Temp_Table INSERT INTO #Map_Temp_Table EXEC dbo.sp_msForEachTable "select convert(varchar(128), '?') as Name" select * from #Map_Temp_Table drop table #Map_Temp_Table

 这时,代码仅仅产生了一个CREATE模板,并没有UPDATE模板。还有,这个CREATE模板没有占位符。SP_map并没有扫描一个按着正常方式调用的存储过程返回的列表。而是由强大的sp_msForEachTable存储过程通过自身进行的扫描。
0
相关文章