码迷,mamicode.com
首页 > 其他好文 > 详细

如何灵活的使用存储过程返回的结果集

时间:2016-01-19 23:29:52      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:

在做报表开发时,遇到这样的需求:

当前要开发的报表A,其数据来源于另一张已经开发好的基础报表B。

(1)由于统计维度不同,从基础报表B获取的数据需要做进一步的处理。

(2)当基础报表B的取数逻辑发生变更时,报表A的取数逻辑也要做相应的变更,保持取数逻辑的一致。

 

经分析,由于报表A和报表B均为存储过程返回的结果集,实为调用和被调用的关系。

于是问题的关键点转化为:存储过程A该如何调用存储过程B,才能灵活的使用存储过程B返回的结果集。

以下案例中隐去真实的业务场景(甄士隐去,贾雨村言)

 

首先,我们对存储过程B,做个微整形,效果如下:

 1 CREATE PROCEDURE usp_MyProc_B
 2 (    
 3     --隐去其他参数,在末尾新增可为空的输入参数@TmpTB
 4     @TmpTB AS VARCHAR(MAX)=‘‘    --全局临时表表名
 5 )
 6 AS
 7 /*************************************************************************
 8 Author:huangcx
 9 DATE  : 2016-01-18
10 -------------------------------------------------------------------------
11 DECLARE @TmpTB VARCHAR(MAX)
12 SET @TmpTB=‘##tmpdata‘ + REPLACE(CONVERT(VARCHAR(100), NEWID()),‘-‘,‘_‘)
13 EXEC usp_MyProc_B @TmpTB
14 *************************************************************************/
15 BEGIN
16     
17     DECLARE @sql VARCHAR(MAX)
18     IF @TmpTB<>‘‘ AND EXISTS(select 1 from tempdb..sysobjects where id=object_id(tempdb..+@TmpTB) and type=U)
19     BEGIN
20         SET @sql = DROP TABLE  + @TmpTB
21         EXEC(@sql)
22     END
23     
24     --处理数据,生成结果集
25     --此处隐去真实的业务场景,代以一个简单的语句
26     SELECT * INTO #tmp FROM p_Project
27     --真事隐去,假语村言
28     
29     --结果集存入全局表,不返回结果集
30     IF @TmpTB<>‘‘ 
31     BEGIN
32         SET @sql = SELECT * INTO + @TmpTB + FROM #tmp
33         EXEC(@sql)
34     END
35     
36     ELSE
37     --返回结果集
38     BEGIN
39         SELECT * FROM #tmp
40     END
41     
42     --删除临时表
43     DROP TABLE #tmp
44 END
45 
46 GO

 

其次,我们获取存储过程B的返回结果集时,需要创建一张表结构与结果集一样的临时表来承载这个结果集。

考虑到后期,存储过程B可能会有所变更,结果集的字段不会是一成不变的,因此需要设法动态的获取结果集的表结构定义。

由于本人功力有限,还请高手路过时,不吝赐教,授予神功秘籍。本人能想到实现方式如下:

  1 CREATE PROCEDURE usp_GetTableDefine
  2 (
  3     @TableName AS VARCHAR(MAX),
  4     @DefineStr AS VARCHAR(MAX)=‘‘ OUTPUT
  5 )
  6 AS
  7 /************************************************************
  8 Author:huangcx
  9 DATE  : 2016-01-18
 10 ------------------------------------------------------------
 11 DECLARE @DefineStr VARCHAR(4000)
 12 EXEC usp_GetTableDefine ‘p_Project‘,@DefineStr output
 13 SELECT @DefineStr
 14 ************************************************************/
 15 BEGIN
 16     
 17     DECLARE @temp TABLE
 18     (
 19         id INT IDENTITY(1, 1),
 20         colname sysname,
 21         typename sysname,
 22         pre smallint,
 23         scale int
 24     )
 25     DECLARE @id int
 26     DECLARE @colname varchar(50)
 27     DECLARE @typename varchar(50)
 28     DECLARE @pre varchar(50)
 29     DECLARE @scale varchar(50)
 30     DECLARE @str varchar(max)
 31     
 32     --普通表
 33     --region
 34     IF EXISTS(select 1 from sysobjects where id=object_id(@TableName) and type=U)
 35     BEGIN
 36         --print ‘普通表‘
 37         INSERT INTO @temp(colname,typename,pre,scale)
 38         SELECT
 39             col.name,
 40             typ.name,
 41             col.prec,
 42             col.scale
 43         FROM sysobjects obj
 44         left join syscolumns col on col.id=obj.id
 45         left join systypes typ on typ.xtype=col.xtype
 46         WHERE obj.type=u
 47         and obj.id=OBJECT_ID(@TableName)
 48         ORDER BY col.colorder
 49     END
 50     --endregion
 51     
 52     --临时表
 53     --region
 54     IF EXISTS(select 1 from tempdb..sysobjects where id=object_id(tempdb..+@TableName) and type=U)
 55     BEGIN
 56         --print ‘临时表‘
 57         INSERT INTO @temp(colname,typename,pre,scale)
 58         SELECT
 59             col.name,
 60             typ.name,
 61             col.prec,
 62             col.scale
 63         FROM tempdb..sysobjects obj
 64         left join tempdb..syscolumns col on col.id=obj.id
 65         left join tempdb..systypes typ on typ.xtype=col.xtype
 66         WHERE obj.type=u
 67         and obj.id=OBJECT_ID(tempdb..+@TableName)
 68         ORDER BY col.colorder
 69     END
 70     --endregion
 71         
 72     --region 取出所有字段定义
 73     SET @DefineStr=‘‘
 74     WHILE EXISTS (SELECT [id] FROM @temp)
 75     BEGIN
 76         
 77         SET ROWCOUNT 1
 78         
 79         SELECT
 80             @id=id,
 81             @colname=colname,
 82             @typename=typename,
 83             @pre=pre,
 84             @scale=scale
 85         FROM @temp
 86         
 87         SET ROWCOUNT 0
 88         
 89         DELETE FROM @temp WHERE id=@id
 90                 
 91         --PRINT ‘ColName:‘ + @colname 
 92         --首行
 93         IF @id = 1
 94         BEGIN
 95             --1.不指定长度和精度
 96             IF @typename IN (sysname,bit,timestamp,bigint,tinyint,smalldatetime,money,smallint,uniqueidentifier,text,ntext,image,geography,geometry,hierarchyid,sql_variant,xml,date,datetime,datetime2,datetimeoffset,int,real,smallmoney,time)
 97             BEGIN
 98                 SET @DefineStr=@DefineStr+[+@colname+] +   + @typename
 99             END
100             --2.只指定长度,不指定精度
101             IF @typename IN (nvarchar,char,varchar,binary,float,nchar,varbinary)
102             BEGIN
103                 SET @DefineStr=@DefineStr+[+@colname+] +   + @typename + (+ @pre +)
104             END
105             --3.同时指定长度和精度
106             IF @typename IN (numeric,decimal)
107             BEGIN
108                 SET @DefineStr=@DefineStr+[+@colname+] +   + @typename + (+ @pre + , + @scale + )
109             END
110         END    
111         --非首行
112         ELSE
113         BEGIN
114             --1.不指定长度和精度
115             IF @typename IN (sysname,bit,timestamp,bigint,tinyint,smalldatetime,money,smallint,uniqueidentifier,text,ntext,image,geography,geometry,hierarchyid,sql_variant,xml,date,datetime,datetime2,datetimeoffset,int,real,smallmoney,time)
116             BEGIN
117                 SET @DefineStr=@DefineStr + , + [+@colname+] +   + @typename
118             END
119             --2.只指定长度,不指定精度
120             IF @typename IN (nvarchar,char,varchar,binary,float,nchar,varbinary)
121             BEGIN
122                 SET @DefineStr=@DefineStr + , + [+@colname+] +   + @typename + (+ @pre +)
123             END
124             --3.同时指定长度和精度
125             IF @typename IN (numeric,decimal)
126             BEGIN
127                 SET @DefineStr=@DefineStr + , + [+@colname+] +   + @typename + (+ @pre + , + @scale + )
128             END
129         END
130         --print @DefineStr
131     END
132     --endregion
133     --select @DefineStr
134 END
135 
136 GO

 

最后,就是存储过程B的实现了。

依旧隐去真实的业务场景,阉割后的存储过程B实现如下:

 1 DECLARE @TmpTB VARCHAR(MAX)            --全局临时表
 2 DECLARE @TableStr VARCHAR(MAX)        --添加字段定义
 3 DECLARE @DataStr VARCHAR(MAX)        --插入数据行
 4 DECLARE @DefineStr VARCHAR(MAX)        --表字段定义
 5 
 6 --设置全局临时表表名
 7 SET @TmpTB=##tmpdata + REPLACE(CONVERT(VARCHAR(100), NEWID()),-,_)
 8 
 9 --调用存储过程,结果集存入全局临时表
10 EXEC usp_MyProc_01 @TmpTB
11 
12 --输出表字段定义
13 EXEC usp_GetTableDefine @TmpTB,@DefineStr output
14 
15 
16 /*
17 这里先创建临时表,再添加表字段。
18 这是由于用EXEC()创建的临时表,也只能在EXEC()中才能使用。
19 */
20 --创建临时表
21 CREATE TABLE #tmp(id int)
22 SET @TableStr = ALTER TABLE #tmp ADD +@DefineStr+ 
23 --PRINT @TableStr
24 EXEC(@TableStr)
25 EXEC(ALTER TABLE #tmp DROP COLUMN id)
26 
27 --数据插入临时表
28 SET @DataStr = INSERT INTO #tmp SELECT * FROM  + @TmpTB
29 PRINT @DataStr
30 EXEC(@DataStr)
31 
32 --删除全局表
33 EXEC(DROP TABLE +@TmpTB)
34 
35 /*
36 这样就可以愉快地使用存储过程返回的结果集了
37 此处省略对结果集的实际处理过程
38 */
39 --使用临时表数据
40 SELECT * FROM #tmp
41 
42 
43 --删除临时表数据
44 DROP TABLE #tmp

 

如何灵活的使用存储过程返回的结果集

标签:

原文地址:http://www.cnblogs.com/newhcx/p/5139924.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!