原文: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

UNION ALL 

SELECT ci.CustId --客户编号
       ,
       ci.CustNam --客户名称
       ,
       ci.ContactBy --联系人
       ,
       ci.Conacts --联系电话
       ,
       ci.Addr -- 联系地址
       ,
       ci.Notes --备注信息
       ,
       ai2.AreaNam --区域名称,省份名称
       ,
       ISNULL(cc.CType, '')     AS CType--合同类型
       ,
       )  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

运行结果:查询出441条数据,其中Union(all) 之前的sql语句查询结果为101条记录;

Union(all) 之后的sql语句查询结果为330条记录。

2、创建视图,将以上SQL查询语句放在视图中:

 ALTER VIEW [dbo].[VGetCustRelatedInfo2]
 AS 

 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

                        UNION ALL 

 SELECT ci.CustId --客户编号
        ,
        ci.CustNam --客户名称
        ,
        ci.ContactBy --联系人
        ,
        ci.Conacts --联系电话
        ,
        ci.Addr -- 联系地址
        ,
        ci.Notes --备注信息
        ,
        ai2.AreaNam --区域名称,省份名称
        ,
        ISNULL(cc.CType, '')     AS CType--合同类型
        ,
        )  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

 GO

调用视图,运行结果:查询出441条数据,其中Union(all) 之前的sql语句查询结果为101条记录;

Union(all) 之后的sql语句查询结果为330条记录。

   3、创建存储过程,代码如下:

 /************************************************************
  * Code formatted by SoftTree SQL Assistant ?v6.5.258
  * Time: 2014/9/12 16:41:46
  ************************************************************/

 GO

 /****** Object:  StoredProcedure [dbo].[SP_GetCustRelatedInfo2]    Script Date: 09/12/2014 

 15:48:17 ******/
 SET ANSI_NULLS ON
 GO

 SET QUOTED_IDENTIFIER ON
 GO

 -- =============================================
 -- Author:      XXX
 -- Create date: XXX
 -- Description: XXX
 -- =============================================
 ALTER PROCEDURE [dbo].[SP_GetCustRelatedInfo2]
     ) --客户编号
      ,
     ) --客户名称
      ,
     )--区域、省份名称
      ,
     @pageSize INT --单页记录条数
      ,
     @pageIndex INT --当前页左索引
      ,
     @totalRowCount INT OUTPUT --输出总记录条数
 AS
 BEGIN
     SET NOCOUNT ON;

     DECLARE @RowStart INT; --定义分页起始位置
     DECLARE @RowEnd INT; --定义分页结束位置

     DECLARE @Sql NVARCHAR(MAX); --拼接SQL语句
     DECLARE @SqlSelectResult NVARCHAR(MAX); --Sql查询结果语句
     DECLARE @SqlCount NVARCHAR(MAX); --Sql Count计数语句

     BEGIN
         ;
         ;
         ;
     END
     ELSE
     BEGIN
         ;
         ;
     END

     )
     BEGIN
         SET @sql =
             'With CTE_CustRelatedInfo as (
                 SELECT  ROW_NUMBER () OVER (ORDER BY t.CustId ASC)  AS RowNumber, t.*
              FROM   (
                  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
                  )
               AS t
                 WHERE 1=1 ';--此处CTE表达式右括号不写,在后面根据条件判断,追加
     END
     ELSE
     BEGIN
         SET @sql =
             'SELECT t.*
              FROM  (
              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
                  )
               AS t
              WHERE 1=1 ';
     END

     IF ISNULL(@custId, '') <> ''
     BEGIN
         --根据客户id查询
         SET @Sql = @Sql + ' AND t.CustId like ''%' + @custId + '%''';
     END

     IF ISNULL(@custNam, '') <> ''
     BEGIN
         --根据客户名称 模糊查询
         SET @Sql = @Sql + ' AND t.CustNam like ''%' + @custNam + '%''';
     END

     IF ISNULL(@areaNam, '') <> ''
     BEGIN
         --根据区域、省份名称
         SET @Sql = @Sql + ' AND t.AreaNam like ''%' + @areaNam + '%''';
     END

     )
     BEGIN
         SET @Sql = @Sql + ') ';

         SET @SqlCount = @Sql +
             ' SELECT @Temp = COUNT(*) FROM CTE_CustRelatedInfo;';

         SET @SqlSelectResult = @Sql +
             ' SELECT * FROM CTE_CustRelatedInfo
 ), @RowStart)
             +
             ), @RowEnd) + ';';

         PRINT (@SqlSelectResult);--打印输出sql语句

         EXEC sp_executesql @SqlSelectResult;--执行sql查询

         EXEC sp_executesql @SqlCount,
              N'@Temp int output',
              @totalRowCount OUTPUT ; --执行count统计
     END
     ELSE
     BEGIN
         SET @Sql = @sql + ' order by t.CustId ASC ';
         ; --总记录数
         PRINT (@Sql);--打印输出sql语句
         EXEC (@Sql);----打印输出sql语句
     END

     SET NOCOUNT OFF;
 END
 GO

  调用存储过程 :

  DECLARE @totalRowCount INT
  EXEC SP_GetCustRelatedInfo2 '','','',10000,1,@totalRowCount OUT

运行结果:查询出330条记录。

     以上结果说明:Sql Server 存储过程中查询语句无法直接使用 Union(All)。使用之后,程序不报错,但是查询结果会丢失Union(All)之前的所有查询记录,只保留最后一个Union(All)之后查询语句的查询结果记录。

     解决方法:

    方案1:先创建视图,将使用Union(All)关键字的sql查询语句放在视图中,然后再存储过程中调用视图。如下:

 USE [BPMIS_TEST]
 GO

 /****** Object:  StoredProcedure [dbo].[SP_GetCustRelatedInfo2]    Script Date: 09/12/2014 15:48:17 ******/
 SET ANSI_NULLS ON
 GO

 SET QUOTED_IDENTIFIER ON
 GO

 -- =============================================
 -- Author:        张传宁
 -- Create date: 2014-9-11
 -- Description:    获取对账单评估明细表信息列表
 -- =============================================
 ALTER PROCEDURE [dbo].[SP_GetCustRelatedInfo2]
     ) --客户编号
      ,
     ) --客户名称
      ,
     )--区域、省份名称
      ,
     @pageSize INT --单页记录条数
      ,
     @pageIndex INT --当前页左索引
      ,
     @totalRowCount INT OUTPUT --输出总记录条数
 AS
 BEGIN
     SET NOCOUNT ON;

     DECLARE @RowStart INT; --定义分页起始位置
     DECLARE @RowEnd INT; --定义分页结束位置

     DECLARE @Sql NVARCHAR(MAX); --拼接SQL语句
     DECLARE @SqlSelectResult NVARCHAR(MAX); --Sql查询结果语句
     DECLARE @SqlCount NVARCHAR(MAX); --Sql Count计数语句

     BEGIN
         ;
         ;
         ;
     END
     ELSE
     BEGIN
         ;
         ;
     END

     )
     BEGIN
         SET @sql =
             'With CTE_CustRelatedInfo as (
                 SELECT  ROW_NUMBER () OVER (ORDER BY t.CustId ASC)  AS RowNumber, t.*
              FROM   VGetCustRelatedInfo2 AS t
                 WHERE 1=1 ';--此处CTE表达式右括号不写,在后面根据条件判断,追加
     END
     ELSE
     BEGIN
         SET @sql =
             'SELECT t.*
              FROM  VGetCustRelatedInfo2 AS t
              WHERE 1=1 ';
     END

     IF ISNULL(@custId, '') <> ''
     BEGIN
         --根据客户id查询
         SET @Sql = @Sql + ' AND t.CustId like ''%' + @custId + '%''';
     END

     IF ISNULL(@custNam, '') <> ''
     BEGIN
         --根据客户名称 模糊查询
         SET @Sql = @Sql + ' AND t.CustNam like ''%' + @custNam + '%''';
     END

     IF ISNULL(@areaNam, '') <> ''
     BEGIN
         --根据区域、省份名称
         SET @Sql = @Sql + ' AND t.AreaNam like ''%' + @areaNam + '%''';
     END

     )
     BEGIN
         SET @Sql = @Sql + ') ';

         SET @SqlCount = @Sql +
             ' SELECT @Temp = COUNT(*) FROM CTE_CustRelatedInfo;';

         SET @SqlSelectResult = @Sql +
             ' SELECT * FROM CTE_CustRelatedInfo
 ), @RowStart)
             +
             ), @RowEnd) + ';';

         PRINT (@SqlSelectResult);--打印输出sql语句

         EXEC sp_executesql @SqlSelectResult;--执行sql查询

         EXEC sp_executesql @SqlCount,
              N'@Temp int output',
              @totalRowCount OUTPUT ; --执行count统计
     END
     ELSE
     BEGIN
         SET @Sql = @sql + ' order by t.CustId ASC ';
         ; --总记录数
         PRINT (@Sql);--打印输出sql语句
         EXEC (@Sql);----打印输出sql语句
     END

     SET NOCOUNT OFF;
 END

 GO

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

Sql Server 存储过程中查询数据无法使用 Union(All)的更多相关文章

  1. SQL Server存储过程中使用表值作为输入参数示例

    这篇文章主要介绍了SQL Server存储过程中使用表值作为输入参数示例,使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据,这样 ...

  2. C#同步SQL Server数据库中的数据--数据库同步工具[同步新数据]

    C#同步SQL Server数据库中的数据 1. 先写个sql处理类: using System; using System.Collections.Generic; using System.Dat ...

  3. 使用变量向SQL Server 2008中插入数据

    QT通过ODBC连接数据库SQL Server 2008,进行数据插入时遇到的问题: 先把数据存入变量中,如何使用变量进行插入?插入语句该怎么写? QSqlQuery query(db); query ...

  4. SQL Server 存储过程中处理多个查询条件的几种常见写法分析,我们该用那种写法

    本文出处: http://www.cnblogs.com/wy123/p/5958047.html 最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫,不知道各种 ...

  5. 最通用的ibatis.Net使用sql server存储过程返回分页数据的详细例子

    ibatis.Net是一个比较简单和灵活的ORM框架,今天我分享一个我的项目中使用sql server通用存储过程来分页的一个例子,用ibatis.Net框架统一返回分页数据为IList<Has ...

  6. SQL Server存储过程中防止线程重入处理方式

    对于线程重入,在C#中有lock关键字锁住一个SyncObject,而SQL Server也可用一个表来模拟实现. 先创建一个同步表,相当于C#中的SyncObject,并插入一条记录(初始值为1) ...

  7. 【转】SQL SERVER 存储过程中变量的作用域

    今天遇到一个很有趣的事情,以前没有注意过,所以记下来. 先来看例子. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE ...

  8. SQL Server 存储过程 分页查询

    Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø ...

  9. sql server 存储过程中使用变量表,临时表的分析(续)

    最近,我有一朋友,对我说他的数据库中的很多存储过程,执行都是超时.让我替他看看是什么原因.我一看,原来他的存储过程中用了很多的临时表与变量表.于是我跟他说过犹不及. 在存储过程中使用临时表或变量表,使 ...

随机推荐

  1. Linux service命令

    service命令(其实与其说是命令,不如说是脚本),因为service本身就是一个脚本,这个脚本在/sbin路径下,待后续shell脚本功底好了将去认真去看看这个脚本的内容(可不能被人忽悠了.) s ...

  2. x64内核内存空间结构

    0x00 前言 本文主要是讨论Windows 7 x64下的内核虚拟地址空间的结构,可以利用WiinDBG调试的扩展命令"!CMKD.kvas"来显示x64下的内核虚拟地址空间的整 ...

  3. JDK安装配置

    http://www.runoob.com/java/java-environment-setup.html

  4. 多线程 - CountDownLatch

    一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在当前计数到达 ...

  5. 【转】抛弃EF,20分构建一个属于自己的ORM框架

    链接:http://www.cnblogs.com/irenebbkiss/p/4157364.html

  6. poj 3254

    状态压缩 dp dp[i][j] 为第 i 行状态为 j 的总数 #include <cstdio> #include <cstdlib> #include <cmath ...

  7. PHP Slim 框架初体验之无法访问控制器

    话不多说,先把报错贴出来: 刚开始用slim框架,在设置完自动加载文件和路由文件之后,我写了一个控制器: <?php use \Psr\Http\Message\ServerRequestInt ...

  8. [TypeScript] Reflection and Decorator Metadata

    TypeScript allows you to emit decorator metadata which enables more powerful features through reflec ...

  9. Unity各平台路径总结

    路径是Unity开发中令人头疼的一个问题,根据我的开发经验,现将开发中遇到的路径问题总结如下: 1. 如何读取Application.streamingAssetsPath下的文件? Edit.iOS ...

  10. ACM2055_ctype.h_cctype

    #include<iostream> int main() { using namespace std; int y,count; char x; cin>>count; wh ...