游乐游手机版
首页/数据库/文章详情

SQL Server 2005通用分页存储过程及多表联接应用

时间:2026-04-14 13:01
SQL Server 2005高效分页存储过程详解与优化 在数据库应用开发中,分页查询是处理海量数据列表与报表展示的核心技术。本文将深入分享一个专为SQL Server 2005设计的通用分页存储过程,该过程巧妙利用ROW_NUMBER()函数实现高效数据分片,在保证优异性能的同时,提供了极高的易用

SQL Server 2005高效分页存储过程详解与优化

在数据库应用开发中,分页查询是处理海量数据列表与报表展示的核心技术。本文将深入分享一个专为SQL Server 2005设计的通用分页存储过程,该过程巧妙利用ROW_NUMBER()函数实现高效数据分片,在保证优异性能的同时,提供了极高的易用性与灵活性。

存储过程核心代码解析

以下是经过优化的分页存储过程完整代码。其核心逻辑是通过动态SQL构建,利用ROW_NUMBER()窗口函数为结果集生成连续行号,从而实现精准的数据切片。

复制代码

存储过程代码如下:

if object_ID('[proc_SelectForPager]') is not null
Drop Procedure [proc_SelectForPager]
Go
Create Proc proc_SelectForPager
(
@Sql varchar(max) ,
@Order varchar(4000) ,
@CurrentPage int ,
@PageSize int,
@TotalCount int output
)
As
/*Andy 2012-2-28 */
Declare @Exec_sql nvarchar(max)
Set @Exec_sql='Set @TotalCount=(Select Count(1) From ('+@Sql+') As a)'
Exec sp_executesql @Exec_sql,N'@TotalCount int output',@TotalCount output
Set @Order=isnull(' Order by '+nullif(@Order,''),' Order By getdate()')
if @CurrentPage=1 /*经常会调用第1页,这里做特殊处理,少一层子查询*/
Set @Exec_sql='
;With CTE_Exec As
(
'+@Sql+'
)
Select Top(@pagesize) *,row_number() Over('+@Order+') As r From CTE_Exec Order By r
'
Else
Set @Exec_sql='
;With CTE_Exec As
(
Select *,row_number() Over('+@Order+') As r From ('+@Sql+') As a
)
Select * From CTE_Exec Where r Between (@CurrentPage-1)*@pagesize+1 And @CurrentPage*@pagesize Order By r
'
Exec sp_executesql @Exec_sql,N'@CurrentPage int,@PageSize int',@CurrentPage,@PageSize
Go

存储过程调用方法与实战示例

该分页存储过程设计灵活,能够完美适配单表查询与复杂多表联接等多种数据库应用场景。

1. 单表数据分页查询

对于单表分页需求,直接传入查询语句即可。以下示例演示如何从contacts表中分页获取特定类型的联系人数据:

复制代码

调用示例代码如下:

Exec proc_SelectForPager @Sql = 'Select * from contacts a where a.ContactType=1', -- varchar(max)
@Order = '', -- varchar(4000)
@CurrentPage = 3, -- int
@PageSize = 20, -- int
@TotalCount = 0 -- int

2. 多表联接分页查询

处理涉及多表关联的复杂分页查询同样简便。您只需构建完整的JOIN语句作为参数传入。以下是一个联接staffOUHIST历史表与Staff员工信息表的实战案例:

复制代码

调用示例代码如下:

Exec proc_SelectForPager @Sql =
'Select a.Staff,a.OU,b.FName+b.FName as Name
from staffOUHIST a
inner join Staff b on b.ID=a.Staff and a.ExpiryDate=''30001231''
', -- varchar(max)
@Order = '', -- varchar(4000)
@CurrentPage = 3, -- int
@PageSize = 20, -- int
@TotalCount = 0 -- int

关键注意事项与优化建议:在传入@Sql参数时,查询语句内部应避免使用公共表表达式(CTE)。这是因为存储过程内部已使用CTE进行分页逻辑封装,外部嵌套可能导致语法冲突或执行错误。理解这一设计约束,有助于您构建正确、高效的传入SQL,确保分页存储过程稳定运行。

来源:https://www.jb51.net/article/33538.htm
上一篇Access 导入到SQL Server 2005的方法小结 下一篇Sql Server 2005的1433端口打开局域网访问和进行远程连接
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Oracle 12c安装报OSDBA组不存在?预先创建用户组解决
数据库 · 2026-07-06

Oracle 12c安装报OSDBA组不存在?预先创建用户组解决

在Linux上安装Oracle12c时,“OSDBAgroupdoesnotexist”报错因缺少dba组,需执行groupadddba并将用户加入该组,用id-a验证。Windows不识别dba组,应使用ORA_DBA组。config o文件硬编码OSDBA组名,需检查其值是否为dba。创建组后仍需注意sudo、su或容器等场景下会话上下文未继承新组的问题

高并发系统缓存更新先删缓存还是先更新数据库
数据库 · 2026-07-06

高并发系统缓存更新先删缓存还是先更新数据库

高并发系统中缓存与数据库更新易致数据不一致。先删缓存再更新可能引入脏数据,建议先更新数据库再删缓存。延迟双删、MQ补偿及Canal监听binlog等方案可保证最终一致性,数据库是最终数据源,缓存为加速层。

SQL中DENSE_RANK为何比RANK更符合业务排名逻辑
数据库 · 2026-07-06

SQL中DENSE_RANK为何比RANK更符合业务排名逻辑

在SQL中,RANK()函数因相同排名后跳号,导致TopN查询可能多出数据;而DENSE_RANK()不跳号,排名连续,更符合“第几档”业务语义,避免歧义,常应用于需要连续排名的分档统计场景中。

高并发SQL INSERT锁竞争成为系统瓶颈的原因
数据库 · 2026-07-06

高并发SQL INSERT锁竞争成为系统瓶颈的原因

很多开发者想当然地认为INSERT只会锁定新插入的那一行,但实际情况远比这复杂。它不仅要施加行锁,还需要在检查唯一约束、分配自增ID以及维护二级索引时,额外申请insert intention lock、gap lock、next-key lock,甚至表级auto-inc lock。这些锁并非各自

如何在SQL SELECT语句中使用CASE WHEN函数实现复杂逻辑分支
数据库 · 2026-07-06

如何在SQL SELECT语句中使用CASE WHEN函数实现复杂逻辑分支

CASEWHEN是表达式而非函数,若忘记ELSE或条件顺序写错易导致NULL结果。需注意数据类型隐式转换问题,在WHERE中宜用布尔表达式,ORDERBY中可自定义排序规则,聚合常与SUM COUNT函数搭配使用。避免深层嵌套,不同数据库语法有差异。