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 存储过程中使用变量表,临时表的分析(续)
最近,我有一朋友,对我说他的数据库中的很多存储过程,执行都是超时.让我替他看看是什么原因.我一看,原来他的存储过程中用了很多的临时表与变量表.于是我跟他说过犹不及. 在存储过程中使用临时表或变量表,使 ...
随机推荐
- linux命令之删除
linux删除文件夹非常easy,非常多人还是习惯用rmdir,只是一旦文件夹非空,就陷入深深的苦恼之中,如今使用rm -rf命令就可以. 直接rm就能够了,只是要加两个參数-rf 即:rm -r ...
- java逼出来的递归中间
请珍惜劳动小编成果.这篇文章是原来小编,转载请注明出处. 有些时候我们须要在中途强制跳出递归.并且还是须要一步跳出,而不一层一层的跳出.这时,我们能够採用抛异常的方法来实现. class Test { ...
- Chapter 3 Protecting the Data(3):创建和使用数据库角色
原版的:http://blog.csdn.net/dba_huangzj/article/details/39639365.专题文件夹:http://blog.csdn.net/dba_huangzj ...
- Forbidden You don't have permission to access / on this server.
原文:Forbidden You don't have permission to access / on this server. Forbidden You don't have permissi ...
- SQL Server 备份和还原
SQL Server 备份和还原 SQL Server 备份 恢复模式 SQL Server 数据恢复模式分为三种:完整恢复模式.大容量日志恢复模式.简单恢复模式. 完整恢复模式 默认的恢复模式, ...
- java数据结构系列——排列(2):有序阵列
package Array; /** * 对数组排序.当添加到阵列保持有序数组元素: * @author wl * */ public class MyOrderArray { private lon ...
- Scala课程01
Scala课程01 简介 由于本人刚毕业,也是从事软件开发相关的工作.想再学习一下关于大数据.移动互联网.云计算相关的技术.为我的未来打好基础.并且从零开始学习大数据相关的知识,脚踏实地的走好每一步, ...
- UVA 11987 - Almost Union-Find(并查集)
UVA 11987 - Almost Union-Find 题目链接 题意:给定一些集合,操作1是合并集合,操作2是把集合中一个元素移动到还有一个集合,操作3输出集合的个数和总和 思路:并查集,关键在 ...
- Oracle 11g XE 是 Oracle 数据库的免费版本
Oracle 11g XE 是 Oracle 数据库的免费版本,支持标准版的大部分功能,11g XE 提供 Windows 和 Linux 版本. 做为免费的 Oracle 数据库版本,XE 的限制是 ...
- 面向对象三大特征之多态——Java笔记(七)
多态: 同一个实体同时具有多种形式 编译时的类型有声明该变量时使用的类型决定,运行时的类型有实际赋值给变量的对象决定 如果编译时类型和运行时类型不同,就出现多态 例: clas ...