微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询。
1、先看一段正常的SQL语句,使用了Union(All)查询:

SELECT ci.CustId --客户编号
, ci.CustNam --客户名称
, ci.ContactBy --联系人
, ci.Conacts --联系电话
, ci.Addr -- 联系地址
, ci.Notes --备注信息
, ai2.AreaNam --区域名称,省份名称
, ISNULL(cc.CType, '') AS CType--合同类型
, ISNULL(caat.ArTotal, 0.0) AS ArTotal --截止到当月底,云想系统账欠款余额
FROM CustInfo AS ci INNER JOIN AreaInfo AS ai ON ci.AreaCode = ai.AreaCode INNER JOIN AreaInfo AS ai2 ON ai.PareaCode = ai2.AreaCode LEFT JOIN CustContract AS cc ON cc.CustId = ci.CustId LEFT JOIN CustArApTotal AS caat ON ci.CustId = caat.CustId WHERE ci.CustCatagory = 1
UNION ALL
SELECT ci.CustId --客户编号
, ci.CustNam --客户名称
, ci.ContactBy --联系人
, ci.Conacts --联系电话
, ci.Addr -- 联系地址
, ci.Notes --备注信息
, ai2.AreaNam --区域名称,省份名称
, ISNULL(cc.CType, '') AS CType--合同类型
, ISNULL(caat.ArTotal, 0) AS ArTotal --截止到当月底,云想系统账欠款余额
FROM CustInfo AS ci INNER JOIN AreaInfo AS ai ON ci.AreaCode = ai.AreaCode INNER JOIN AreaInfo AS ai2 ON ai.PareaCode = ai2.AreaCode INNER JOIN CustContract AS cc ON cc.CustId = ci.CustId LEFT JOIN CustArApTotal AS caat ON ci.CustId = caat.CustId WHERE ci.CustCatagory = 2
运行结果:查询出441条数据,其中Union(all) 之前的sql语句查询结果为101条记录;
Union(all) 之后的sql语句查询结果为330条记录。
2、创建视图,将以上SQL查询语句放在视图中:

1 ALTER VIEW [dbo].[VGetCustRelatedInfo2]
2 AS
3
4 SELECT ci.CustId --客户编号
5 , 6 ci.CustNam --客户名称
7 , 8 ci.ContactBy --联系人
9 , 10 ci.Conacts --联系电话
11 , 12 ci.Addr -- 联系地址
13 , 14 ci.Notes --备注信息
15 , 16 ai2.AreaNam --区域名称,省份名称
17 , 18 ISNULL(cc.CType, '') AS CType--合同类型
19 , 20 ISNULL(caat.ArTotal, 0.0) AS ArTotal --截止到当月底,云想系统账欠款余额
21 FROM CustInfo AS ci 22 INNER JOIN AreaInfo AS ai 23 ON ci.AreaCode = ai.AreaCode 24 INNER JOIN AreaInfo AS ai2 25 ON ai.PareaCode = ai2.AreaCode 26 LEFT JOIN CustContract AS cc 27 ON cc.CustId = ci.CustId 28 LEFT JOIN CustArApTotal AS caat 29 ON ci.CustId = caat.CustId 30 WHERE ci.CustCatagory = 1
31
32 UNION ALL
33
34 SELECT ci.CustId --客户编号
35 , 36 ci.CustNam --客户名称
37 , 38 ci.ContactBy --联系人
39 , 40 ci.Conacts --联系电话
41 , 42 ci.Addr -- 联系地址
43 , 44 ci.Notes --备注信息
45 , 46 ai2.AreaNam --区域名称,省份名称
47 , 48 ISNULL(cc.CType, '') AS CType--合同类型
49 , 50 ISNULL(caat.ArTotal, 0) AS ArTotal --截止到当月底,云想系统账欠款余额
51 FROM CustInfo AS ci 52 INNER JOIN AreaInfo AS ai 53 ON ci.AreaCode = ai.AreaCode 54 INNER JOIN AreaInfo AS ai2 55 ON ai.PareaCode = ai2.AreaCode 56 INNER JOIN CustContract AS cc 57 ON cc.CustId = ci.CustId 58 LEFT JOIN CustArApTotal AS caat 59 ON ci.CustId = caat.CustId 60 WHERE ci.CustCatagory = 2
61
62
63
64
65
66 GO
调用视图,运行结果:查询出441条数据,其中Union(all) 之前的sql语句查询结果为101条记录;
Union(all) 之后的sql语句查询结果为330条记录。
3、创建存储过程,代码如下:

1 /************************************************************ 2 * Code formatted by SoftTree SQL Assistant ?v6.5.258 3 * Time: 2014/9/12 16:41:46 4 ************************************************************/
5
6 GO
7
8 /****** Object: StoredProcedure [dbo].[SP_GetCustRelatedInfo2] Script Date: 09/12/2014 9
10 15:48:17 ******/
11 SET ANSI_NULLS ON
12 GO
13
14 SET QUOTED_IDENTIFIER ON
15 GO
16
17
18
19 -- =============================================
20 -- Author: XXX
21 -- Create date: XXX
22 -- Description: XXX
23 -- =============================================
24 ALTER PROCEDURE [dbo].[SP_GetCustRelatedInfo2]
25 @custId NVARCHAR(30) --客户编号
26 , 27 @custNam NVARCHAR(1000) --客户名称
28 , 29 @areaNam NVARCHAR(30)--区域、省份名称
30 , 31 @pageSize INT --单页记录条数
32 , 33 @pageIndex INT --当前页左索引
34 , 35 @totalRowCount INT OUTPUT --输出总记录条数
36 AS
37 BEGIN
38 SET NOCOUNT ON; 39
40 DECLARE @RowStart INT; --定义分页起始位置
41 DECLARE @RowEnd INT; --定义分页结束位置
42
43 DECLARE @Sql NVARCHAR(MAX); --拼接SQL语句
44 DECLARE @SqlSelectResult NVARCHAR(MAX); --Sql查询结果语句
45 DECLARE @SqlCount NVARCHAR(MAX); --Sql Count计数语句
46
47 IF @pageIndex > 0
48 BEGIN
49 SET @pageIndex = @pageIndex -1; 50 SET @RowStart = @pageSize * @pageIndex + 1; 51 SET @RowEnd = @RowStart + @pageSize - 1; 52 END
53 ELSE
54 BEGIN
55 SET @RowStart = 1; 56 SET @RowEnd = 999999; 57 END
58
59 IF ISNULL(@pageSize, 0) <> 0
60 BEGIN
61 SET @sql =
62 'With CTE_CustRelatedInfo as ( 63 SELECT ROW_NUMBER () OVER (ORDER BY t.CustId ASC) AS RowNumber, t.* 64 FROM ( 65 SELECT ci.CustId --客户编号 66 , 67 ci.CustNam --客户名称 68 , 69 ci.ContactBy --联系人 70 , 71 ci.Conacts --联系电话 72 , 73 ci.Addr -- 联系地址 74 , 75 ci.Notes --备注信息 76 , 77 ai2.AreaNam --区域名称,省份名称 78 , 79 ISNULL(cc.CType, '') AS CType--合同类型 80 , 81 ISNULL(caat.ArTotal, 0.0) AS ArTotal --截止到当月底,云想系统账欠款余额 82 FROM CustInfo AS ci 83 INNER JOIN AreaInfo AS ai 84 ON ci.AreaCode = ai.AreaCode 85 INNER JOIN AreaInfo AS ai2 86 ON ai.PareaCode = ai2.AreaCode 87 LEFT JOIN CustContract AS cc 88 ON cc.CustId = ci.CustId 89 LEFT JOIN CustArApTotal AS caat 90 ON ci.CustId = caat.CustId 91 WHERE ci.CustCatagory = 1 92
93 UNION ALL 94
95 SELECT ci.CustId --客户编号 96 , 97 ci.CustNam --客户名称 98 , 99 ci.ContactBy --联系人 100 , 101 ci.Conacts --联系电话 102 , 103 ci.Addr -- 联系地址 104 , 105 ci.Notes --备注信息 106 , 107 ai2.AreaNam --区域名称,省份名称 108 , 109 ISNULL(cc.CType, '') AS CType--合同类型 110 , 111 ISNULL(caat.ArTotal, 0) AS ArTotal --截止到当月底,云想系统账欠款余额 112 FROM CustInfo AS ci 113 INNER JOIN AreaInfo AS ai 114 ON ci.AreaCode = ai.AreaCode 115 INNER JOIN AreaInfo AS ai2 116 ON ai.PareaCode = ai2.AreaCode 117 INNER JOIN CustContract AS cc 118 ON cc.CustId = ci.CustId 119 LEFT JOIN CustArApTotal AS caat 120 ON ci.CustId = caat.CustId 121 WHERE ci.CustCatagory = 2 122 ) 123 AS t 124 WHERE 1=1 ';--此处CTE表达式右括号不写,在后面根据条件判断,追加
125 END
126 ELSE
127 BEGIN
128 SET @sql =
129 'SELECT t.* 130 FROM ( 131 SELECT ci.CustId --客户编号 132 ,ci.CustNam --客户名称 133 , 134 ci.ContactBy --联系人 135 , 136 ci.Conacts --联系电话 137 , 138 ci.Addr -- 联系地址 139 , 140 ci.Notes --备注信息 141 , 142 ai2.AreaNam --区域名称,省份名称 143 , 144 ISNULL(cc.CType, '') AS CType--合同类型 145 , 146 ISNULL(caat.ArTotal, 0.0) AS ArTotal --截止到当月底,云想系统账欠款余额 147 FROM CustInfo AS ci 148 INNER JOIN AreaInfo AS ai 149 ON ci.AreaCode = ai.AreaCode 150 INNER JOIN AreaInfo AS ai2 151 ON ai.PareaCode = ai2.AreaCode 152 LEFT JOIN CustContract AS cc 153 ON cc.CustId = ci.CustId 154 LEFT JOIN CustArApTotal AS caat 155 ON ci.CustId = caat.CustId 156 WHERE ci.CustCatagory = 1 157
158 UNION ALL 159
160 SELECT ci.CustId --客户编号 161 , 162 ci.CustNam --客户名称 163 , 164 ci.ContactBy --联系人 165 , 166 ci.Conacts --联系电话 167 , 168 ci.Addr -- 联系地址 169 , 170 ci.Notes --备注信息 171 , 172 ai2.AreaNam --区域名称,省份名称 173 , 174 ISNULL(cc.CType, '') AS CType--合同类型 175 , 176 ISNULL(caat.ArTotal, 0) AS ArTotal --截止到当月底,云想系统账欠款余额 177 FROM CustInfo AS ci 178 INNER JOIN AreaInfo AS ai 179 ON ci.AreaCode = ai.AreaCode 180 INNER JOIN AreaInfo AS ai2 181 ON ai.PareaCode = ai2.AreaCode 182 INNER JOIN CustContract AS cc 183 ON cc.CustId = ci.CustId 184 LEFT JOIN CustArApTotal AS caat 185 ON ci.CustId = caat.CustId 186 WHERE ci.CustCatagory = 2 187 ) 188 AS t 189 WHERE 1=1 '; 190 END
191
192 IF ISNULL(@custId, '') <> ''
193 BEGIN
194 --根据客户id查询
195 SET @Sql = @Sql + ' AND t.CustId like ''%' + @custId + '%'''; 196 END
197
198 IF ISNULL(@custNam, '') <> ''
199 BEGIN
200 --根据客户名称 模糊查询
201 SET @Sql = @Sql + ' AND t.CustNam like ''%' + @custNam + '%'''; 202 END
203
204 IF ISNULL(@areaNam, '') <> ''
205 BEGIN
206 --根据区域、省份名称
207 SET @Sql = @Sql + ' AND t.AreaNam like ''%' + @areaNam + '%'''; 208 END
209
210 IF ISNULL(@pageSize, 0) <> 0
211 BEGIN
212 SET @Sql = @Sql + ') '; 213
214 SET @SqlCount = @Sql +
215 ' SELECT @Temp = COUNT(*) FROM CTE_CustRelatedInfo;'; 216
217 SET @SqlSelectResult = @Sql +
218 ' SELECT * FROM CTE_CustRelatedInfo 219 WHERE RowNumber Between ' + CONVERT(VARCHAR(10), @RowStart) 220 +
221 ' And ' + CONVERT(VARCHAR(10), @RowEnd) + ';'; 222
223 PRINT (@SqlSelectResult);--打印输出sql语句
224
225 EXEC sp_executesql @SqlSelectResult;--执行sql查询
226
227 EXEC sp_executesql @SqlCount, 228 N'@Temp int output', 229 @totalRowCount OUTPUT ; --执行count统计
230 END
231 ELSE
232 BEGIN
233 SET @Sql = @sql + ' order by t.CustId ASC '; 234 SET @totalRowCount = 0; --总记录数
235 PRINT (@Sql);--打印输出sql语句
236 EXEC (@Sql);----打印输出sql语句
237 END
238
239 SET NOCOUNT OFF; 240 END
241 GO
调用存储过程 :
DECLARE @totalRowCount INT
EXEC SP_GetCustRelatedInfo2 '','','',10000,1,@totalRowCount OUT
运行结果:查询出330条记录。
以上结果说明:Sql Server 存储过程中查询语句无法直接使用 Union(All)。使用之后,程序不报错,但是查询结果会丢失Union(All)之前的所有查询记录,只保留最后一个Union(All)之后查询语句的查询结果记录。
解决方法:
方案1:先创建视图,将使用Union(All)关键字的sql查询语句放在视图中,然后再存储过程中调用视图。如下:

1 USE [BPMIS_TEST]
2 GO
3
4 /****** Object: StoredProcedure [dbo].[SP_GetCustRelatedInfo2] Script Date: 09/12/2014 15:48:17 ******/
5 SET ANSI_NULLS ON
6 GO
7
8 SET QUOTED_IDENTIFIER ON
9 GO
10
11
12
13 -- =============================================
14 -- Author: 张传宁
15 -- Create date: 2014-9-11
16 -- Description: 获取对账单评估明细表信息列表
17 -- =============================================
18 ALTER PROCEDURE [dbo].[SP_GetCustRelatedInfo2]
19 @custId NVARCHAR(30) --客户编号
20 , 21 @custNam NVARCHAR(1000) --客户名称
22 , 23 @areaNam NVARCHAR(30)--区域、省份名称
24 , 25 @pageSize INT --单页记录条数
26 , 27 @pageIndex INT --当前页左索引
28 , 29 @totalRowCount INT OUTPUT --输出总记录条数
30 AS
31 BEGIN
32 SET NOCOUNT ON; 33
34 DECLARE @RowStart INT; --定义分页起始位置
35 DECLARE @RowEnd INT; --定义分页结束位置
36
37 DECLARE @Sql NVARCHAR(MAX); --拼接SQL语句
38 DECLARE @SqlSelectResult NVARCHAR(MAX); --Sql查询结果语句
39 DECLARE @SqlCount NVARCHAR(MAX); --Sql Count计数语句
40
41 IF @pageIndex > 0
42 BEGIN
43 SET @pageIndex = @pageIndex -1; 44 SET @RowStart = @pageSize * @pageIndex + 1; 45 SET @RowEnd = @RowStart + @pageSize - 1; 46 END
47 ELSE
48 BEGIN
49 SET @RowStart = 1; 50 SET @RowEnd = 999999; 51 END
52
53 IF ISNULL(@pageSize, 0) <> 0
54 BEGIN
55 SET @sql =
56 'With CTE_CustRelatedInfo as ( 57 SELECT ROW_NUMBER () OVER (ORDER BY t.CustId ASC) AS RowNumber, t.* 58 FROM VGetCustRelatedInfo2 AS t 59 WHERE 1=1 ';--此处CTE表达式右括号不写,在后面根据条件判断,追加
60 END
61 ELSE
62 BEGIN
63 SET @sql =
64 'SELECT t.* 65 FROM VGetCustRelatedInfo2 AS t 66 WHERE 1=1 '; 67 END
68
69 IF ISNULL(@custId, '') <> ''
70 BEGIN
71 --根据客户id查询
72 SET @Sql = @Sql + ' AND t.CustId like ''%' + @custId + '%'''; 73 END
74
75 IF ISNULL(@custNam, '') <> ''
76 BEGIN
77 --根据客户名称 模糊查询
78 SET @Sql = @Sql + ' AND t.CustNam like ''%' + @custNam + '%'''; 79 END
80
81 IF ISNULL(@areaNam, '') <> ''
82 BEGIN
83 --根据区域、省份名称
84 SET @Sql = @Sql + ' AND t.AreaNam like ''%' + @areaNam + '%'''; 85 END
86
87 IF ISNULL(@pageSize, 0) <> 0
88 BEGIN
89 SET @Sql = @Sql + ') '; 90
91 SET @SqlCount = @Sql +
92 ' SELECT @Temp = COUNT(*) FROM CTE_CustRelatedInfo;'; 93
94 SET @SqlSelectResult = @Sql +
95 ' SELECT * FROM CTE_CustRelatedInfo 96 WHERE RowNumber Between ' + CONVERT(VARCHAR(10), @RowStart) 97 +
98 ' And ' + CONVERT(VARCHAR(10), @RowEnd) + ';'; 99
100 PRINT (@SqlSelectResult);--打印输出sql语句
101
102 EXEC sp_executesql @SqlSelectResult;--执行sql查询
103
104 EXEC sp_executesql @SqlCount, 105 N'@Temp int output', 106 @totalRowCount OUTPUT ; --执行count统计
107 END
108 ELSE
109 BEGIN
110 SET @Sql = @sql + ' order by t.CustId ASC '; 111 SET @totalRowCount = 0; --总记录数
112 PRINT (@Sql);--打印输出sql语句
113 EXEC (@Sql);----打印输出sql语句
114 END
115
116 SET NOCOUNT OFF; 117 END
118
119
120
121 GO
方案2:在存储过程中先创建临时表,将多个Union(All)前后的sql查询语句的查询结果插入到临时表中,然后操作临时表,最后做其他的处理。