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

运行结果:查询出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
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 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]
@custId NVARCHAR(30) --客户编号
,
@custNam NVARCHAR(1000) --客户名称
,
@areaNam NVARCHAR(30)--区域、省份名称
,
@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计数语句 IF @pageIndex > 0
BEGIN
SET @pageIndex = @pageIndex -1;
SET @RowStart = @pageSize * @pageIndex + 1;
SET @RowEnd = @RowStart + @pageSize - 1;
END
ELSE
BEGIN
SET @RowStart = 1;
SET @RowEnd = 999999;
END IF ISNULL(@pageSize, 0) <> 0
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 IF ISNULL(@pageSize, 0) <> 0
BEGIN
SET @Sql = @Sql + ') '; SET @SqlCount = @Sql +
' SELECT @Temp = COUNT(*) FROM CTE_CustRelatedInfo;'; SET @SqlSelectResult = @Sql +
' SELECT * FROM CTE_CustRelatedInfo
WHERE RowNumber Between ' + CONVERT(VARCHAR(10), @RowStart)
+
' And ' + CONVERT(VARCHAR(10), @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 ';
SET @totalRowCount = 0; --总记录数
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]
@custId NVARCHAR(30) --客户编号
,
@custNam NVARCHAR(1000) --客户名称
,
@areaNam NVARCHAR(30)--区域、省份名称
,
@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计数语句 IF @pageIndex > 0
BEGIN
SET @pageIndex = @pageIndex -1;
SET @RowStart = @pageSize * @pageIndex + 1;
SET @RowEnd = @RowStart + @pageSize - 1;
END
ELSE
BEGIN
SET @RowStart = 1;
SET @RowEnd = 999999;
END IF ISNULL(@pageSize, 0) <> 0
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 IF ISNULL(@pageSize, 0) <> 0
BEGIN
SET @Sql = @Sql + ') '; SET @SqlCount = @Sql +
' SELECT @Temp = COUNT(*) FROM CTE_CustRelatedInfo;'; SET @SqlSelectResult = @Sql +
' SELECT * FROM CTE_CustRelatedInfo
WHERE RowNumber Between ' + CONVERT(VARCHAR(10), @RowStart)
+
' And ' + CONVERT(VARCHAR(10), @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 ';
SET @totalRowCount = 0; --总记录数
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. T-SQL使用案例——结果数据前面自动补0

    原文:T-SQL使用案例--结果数据前面自动补0 现象: 在开发的过程中,往往需要数字和字符串互转.在转换的过程中,可能需要把1编程00001,这样的格式.实现这种样子是有非常多的方法,本文主要提供一 ...

  2. 跳跃Java一些周期,双跳FOR周期

    今天写的代码写在一个双层for周期,目前仍在使用Iterator,大致意思是假定在第二个周期在排位赛中给了整个双回路跳. 刚開始,直接使用break.巴拉巴拉的敲了一堆代码,信心满满的就直接执行.等到 ...

  3. AndroidMainifest标签说明2——&lt;activity&gt;

    格公式: <activity android:allowTaskReparenting=["true" | "false"] android:always ...

  4. MEF初体验之二:定义组合部件和契约

    组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...

  5. 一个MP3播放的插件jPlayer

    Jplayer小样   最近应公司要求需要一个MP3播放的插件,网上找了很多插件,看来看去还是jPlayer用着最舒服也最容易扩展.所以就找了个资料研究了下,简单做了个小DEMO.支持实时控制列表,常 ...

  6. Oracle 数据恢复指导具体解释

    1.数据恢复指导 : 高速检測.分析和修复故障 最大程度地降低停机故障和执行时故障 将对用户的干扰降到最低 用户界面:    --EM GUI 界面 (多个路径)    --RMAN 命令行 支持的数 ...

  7. BMP文件格式及读写

    转 http://blog.csdn.net/pkueecser/article/details/5579604 http://blog.csdn.net/pkueecser/article/deta ...

  8. PHP操作XML文件学习笔记

    原文:PHP操作XML文件学习笔记 XML文件属于标签语言,可以通过自定义标签存储数据,其主要作用也是作为存储数据. 对于XML的操作包括遍历,生成,修改,删除等其他类似的操作.PHP对于XML的操作 ...

  9. JAXB 操作XML 与 Object

    Java Architecture for XML Binding) 是一个业界的标准,是一项能够依据XML Schema产生Java类的技术.是一种xml与object映射绑定技术标准. JDK5下 ...

  10. Is it always safe to call getClass() within the subclass constructor?(转)

    14down votefavorite   An article on classloading states that the method getClass() should not be cal ...