SQL Server的通用分頁存儲過程 未使用游標(biāo),速度更快!
正常情況下,SQL Server服務(wù)器上會對使用頻率大的Table建立合適的索引
這樣能大幅度的提高數(shù)據(jù)庫本身的數(shù)據(jù)檢索速度,建立索引的方法就不細(xì)說了
如果需要返回大量數(shù)據(jù),從幾百行到幾萬行,甚至幾十萬行數(shù)據(jù)
這時會發(fā)現(xiàn)響應(yīng)速度越來越慢,甚至發(fā)生響應(yīng)超時的錯誤
為了解決這種大數(shù)據(jù)量請求的問題,就不得不使用分頁模式了
在這方面,JDBC就強(qiáng)悍得多,它可以將指定的行數(shù)和SQL請求一并發(fā)送給SQL Server,這樣只返回分頁后的數(shù)據(jù),JDBC的原理還不清楚,但在實(shí)際使用中,速度還是非??斓?
如果沒辦法使用JDBC,最常用的方法就是存儲過程了!
我在寫這個分頁存儲之前,參考了網(wǎng)上的大量相關(guān)文章,可以通過關(guān)鍵字:SQL Server 分頁 進(jìn)行搜索
他們主要都是利用SQL中的Top方法,并且對所檢索的數(shù)據(jù)結(jié)構(gòu)要求有標(biāo)識列,如果沒有標(biāo)識列,或者是聯(lián)合主鍵,那么就會非常麻煩了。而且對應(yīng)用里原有的SQL檢索部分需要修改的地方較多,工作量較大。
因此,我在寫這個存儲之前就要求一定要對原有的SQL腳本最大程度的兼容
經(jīng)過一個下午的時間,和我一個同事(絕對是高手)的共同努力下,摸索出了以下的思路:
1、確定存儲的輸入?yún)?shù):
1)SQL腳本,該參數(shù)接收完整的、正確的SQL檢索文本,可將原應(yīng)用中寫好的SQL腳本直接傳入
2)每頁的數(shù)據(jù)容量,就是一頁有多少條數(shù)據(jù)
3)當(dāng)前頁碼
2、確定分頁機(jī)制:
1)執(zhí)行傳入的SQL腳本,并將結(jié)果生成臨時表
2)修改臨時表的結(jié)構(gòu),增加標(biāo)識列字段
3)根據(jù)標(biāo)識列字段,計算出指定頁碼內(nèi)的記錄范圍,并返回
4)返回總數(shù)據(jù)條數(shù),用于客戶端進(jìn)行分頁顯示
根據(jù)以上的思路,編寫出以下通用的分頁存儲過程:
[code]
--// ============================
--// SQL Server通用分頁存儲過程
--// Author : netwild
--// date : 2010/07/22
--// Email : netwild@163.com
--// QQ : 52100641(網(wǎng)無忌)
--// ============================
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE PROC execByPage
@sqlQuery varchar(2000), --//輸入?yún)?shù):SQL檢索語句或表名
@pageSize int, --//輸入?yún)?shù):每頁顯示記錄條數(shù)
@pageIndex int --//輸入?yún)?shù):當(dāng)前頁碼
AS
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
declare @tmpTableName varchar(50)
set @tmpTableName = '##TB1516_' + replace(cast(newid() as varchar(40)),'-','') --//生成隨機(jī)臨時表名稱
declare @subIndex int
set @subIndex = charindex('from',@sqlQuery)
if (@subIndex > 0)
begin --//帶FROM的標(biāo)準(zhǔn)檢索語句
declare @sqlQuery1 varchar(2000)
declare @sqlQuery2 varchar(2000)
set @sqlQuery1 = substring(@sqlQuery,1,@subIndex - 1)
set @sqlQuery2 = substring(@sqlQuery,@subIndex,len(@sqlQuery))
set @sqlQuery = @sqlQuery1 + ',IDENTITY(numeric,1,1) as ID1516 into ' + @tmpTableName + ' ' + @sqlQuery2
end
else --//不帶FROM的表名
begin
set @sqlQuery = 'select *,IDENTITY(numeric,1,1) as ID1516 into ' + @tmpTableName + ' from' + @sqlQuery
end
exec(@sqlQuery) --//建立并初始化臨時表數(shù)據(jù)
declare @indexStart varchar(20),@indexEnd varchar(20)
set @indexStart = cast((@pageIndex-1)*@pageSize+1 as varchar(20)) --//數(shù)據(jù)起始行ID
set @indexEnd = cast(@pageIndex * @pageSize as varchar(20)) --//數(shù)據(jù)結(jié)束行ID
exec('select * from ' + @tmpTableName + ' where ID1516 between ' + @indexStart + ' and ' + @indexEnd) --//檢索該頁數(shù)據(jù)
exec('select max(ID1516) as recordCount from ' + @tmpTableName) --//提取總條數(shù)
exec('drop table ' + @tmpTableName) --//刪除臨時表
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
[/code]
相關(guān)文章
SQL Server中調(diào)用C#類中的方法實(shí)例(使用.NET程序集)
這篇文章主要介紹了SQL Server中調(diào)用C#類中的方法實(shí)例(使用.NET程序集),本文實(shí)現(xiàn)了在SQL Server中調(diào)用C#寫的類及方法,需要的朋友可以參考下2014-10-10驅(qū)動程序無法通過使用安全套接字層(SSL)加密與?SQL?Server?建立安全連接,錯誤:“The?serve
這篇文章主要介紹了驅(qū)動程序無法通過使用安全套接字層(SSL)加密與?SQL?Server?建立安全連接,錯誤:“The?server?selected?protocol?version?TLS10?is?not?accepted?by?client,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03Sqlserver 存儲過程中結(jié)合事務(wù)的代碼
Sqlserver 存儲過程中使用事務(wù)2010-06-06sql語句中如何將datetime格式的日期轉(zhuǎn)換為yy-mm-dd格式
sql語句中如何將datetime格式的日期轉(zhuǎn)換為yy-mm-dd格式...2007-10-10SQL Server 總結(jié)復(fù)習(xí) (二)
SQL Server 總結(jié)復(fù)習(xí),學(xué)習(xí)sqlserver的朋友可以參考下2012-08-08SQL Server游標(biāo)的使用/關(guān)閉/釋放/優(yōu)化小結(jié)
游標(biāo)打破了這一查詢的思考是面向集合的規(guī)則,游標(biāo)使得我們思考方式變?yōu)橹鹦羞M(jìn)行,接下來為大家介紹下游標(biāo)的使用感興趣的朋友可以參考下哈,希望可以幫助到你2013-03-03