微軟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查詢語句的查詢結果插入到臨時表中,然后操作臨時表,最后做其他的處理。

