Sql Server 存储过程中查询数据无法使用 Union(All)
原文: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)的更多相关文章
- SQL Server存储过程中使用表值作为输入参数示例
这篇文章主要介绍了SQL Server存储过程中使用表值作为输入参数示例,使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据,这样 ...
- C#同步SQL Server数据库中的数据--数据库同步工具[同步新数据]
C#同步SQL Server数据库中的数据 1. 先写个sql处理类: using System; using System.Collections.Generic; using System.Dat ...
- 使用变量向SQL Server 2008中插入数据
QT通过ODBC连接数据库SQL Server 2008,进行数据插入时遇到的问题: 先把数据存入变量中,如何使用变量进行插入?插入语句该怎么写? QSqlQuery query(db); query ...
- SQL Server 存储过程中处理多个查询条件的几种常见写法分析,我们该用那种写法
本文出处: http://www.cnblogs.com/wy123/p/5958047.html 最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫,不知道各种 ...
- 最通用的ibatis.Net使用sql server存储过程返回分页数据的详细例子
ibatis.Net是一个比较简单和灵活的ORM框架,今天我分享一个我的项目中使用sql server通用存储过程来分页的一个例子,用ibatis.Net框架统一返回分页数据为IList<Has ...
- SQL Server存储过程中防止线程重入处理方式
对于线程重入,在C#中有lock关键字锁住一个SyncObject,而SQL Server也可用一个表来模拟实现. 先创建一个同步表,相当于C#中的SyncObject,并插入一条记录(初始值为1) ...
- 【转】SQL SERVER 存储过程中变量的作用域
今天遇到一个很有趣的事情,以前没有注意过,所以记下来. 先来看例子. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE ...
- SQL Server 存储过程 分页查询
Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø ...
- sql server 存储过程中使用变量表,临时表的分析(续)
最近,我有一朋友,对我说他的数据库中的很多存储过程,执行都是超时.让我替他看看是什么原因.我一看,原来他的存储过程中用了很多的临时表与变量表.于是我跟他说过犹不及. 在存储过程中使用临时表或变量表,使 ...
随机推荐
- T-SQL使用案例——结果数据前面自动补0
原文:T-SQL使用案例--结果数据前面自动补0 现象: 在开发的过程中,往往需要数字和字符串互转.在转换的过程中,可能需要把1编程00001,这样的格式.实现这种样子是有非常多的方法,本文主要提供一 ...
- 跳跃Java一些周期,双跳FOR周期
今天写的代码写在一个双层for周期,目前仍在使用Iterator,大致意思是假定在第二个周期在排位赛中给了整个双回路跳. 刚開始,直接使用break.巴拉巴拉的敲了一堆代码,信心满满的就直接执行.等到 ...
- AndroidMainifest标签说明2——<activity>
格公式: <activity android:allowTaskReparenting=["true" | "false"] android:always ...
- MEF初体验之二:定义组合部件和契约
组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...
- 一个MP3播放的插件jPlayer
Jplayer小样 最近应公司要求需要一个MP3播放的插件,网上找了很多插件,看来看去还是jPlayer用着最舒服也最容易扩展.所以就找了个资料研究了下,简单做了个小DEMO.支持实时控制列表,常 ...
- Oracle 数据恢复指导具体解释
1.数据恢复指导 : 高速检測.分析和修复故障 最大程度地降低停机故障和执行时故障 将对用户的干扰降到最低 用户界面: --EM GUI 界面 (多个路径) --RMAN 命令行 支持的数 ...
- BMP文件格式及读写
转 http://blog.csdn.net/pkueecser/article/details/5579604 http://blog.csdn.net/pkueecser/article/deta ...
- PHP操作XML文件学习笔记
原文:PHP操作XML文件学习笔记 XML文件属于标签语言,可以通过自定义标签存储数据,其主要作用也是作为存储数据. 对于XML的操作包括遍历,生成,修改,删除等其他类似的操作.PHP对于XML的操作 ...
- JAXB 操作XML 与 Object
Java Architecture for XML Binding) 是一个业界的标准,是一项能够依据XML Schema产生Java类的技术.是一种xml与object映射绑定技术标准. JDK5下 ...
- 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 ...