• Sql Server 存储过程中查询数据无法使用 Union(All)


      微软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
    View Code

     

     运行结果:查询出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
    View Code

    调用视图,运行结果:查询出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
    View Code

      调用存储过程 :

      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
    View Code

         方案2:在存储过程中先创建临时表,将多个Union(All)前后的sql查询语句的查询结果插入到临时表中,然后操作临时表,最后做其他的处理。

  • 相关阅读:
    Python数据结构之字符串
    Python中的logging模块
    Python资源大全中文版
    test
    Python数据结构之元组
    Python之StringIO和BytesIO
    Python标准库之pathlib
    Ubuntu下安装pyenv管理多版本python
    生成器 Generator
    CIDR网段格式
  • 原文地址:https://www.cnblogs.com/SavionZhang/p/3968726.html
Copyright © 2020-2023  润新知