微軟Sql Server數據庫中,書寫存儲過程時,關於查詢數據,沒法使用Union(All)關聯多個查詢。html
一、先看一段正常的SQL語句,使用了Union(All)查詢:sql
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條記錄。ide
二、建立視圖,將以上SQL查詢語句放在視圖中:post
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條記錄;url
Union(all) 以後的sql語句查詢結果爲330條記錄。spa
三、建立存儲過程,代碼以下:code
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
調用存儲過程 :orm
DECLARE @totalRowCount INT
EXEC SP_GetCustRelatedInfo2 '','','',10000,1,@totalRowCount OUThtm
運行結果:查詢出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查詢語句的查詢結果插入到臨時表中,而後操做臨時表,最後作其餘的處理。