下面的是SqlServer 通用分頁查詢的存儲過程,不過此方法只適合單表查詢。
CREATE PROCEDURE CommonPageIndexSearch @fileds NVARCHAR(200)='*',--需要查詢的字段 @orderField NVARCHAR(10)='Id',--排序字段,一般分頁查詢都用主鍵作為排序字段 @tableName NVARCHAR(20),--需要查詢的表名 @condition NVARCHAR(400),--查詢條件,如:AND 1=1 @begin NVARCHAR(10),--分頁查詢開始行 @end NVARCHAR(10)----分頁查詢結束行 AS BEGIN DECLARE @SQL NVARCHAR(4000); SET @SQL='SELECT * FROM (SELECT ROW_NUMBER(ORDER BY '+@orderField+') AS Line' +@fileds+' FROM '+@tableName +' WHERE 1=1 '+@condition+')A WHERE A.Line>'+@begin+' AND A.Line<='+@end; EXECUTE(@SQL); END
有個更復雜的通用分頁查詢存儲過程,結合了正則表達式,支持多表聯接查詢
GO /****** Object: StoredProcedure [dbo].[CustomPaged] Script Date: 2013/11/4 0:42:10 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- DROP PROC[dbo].[CustomPaged] go CREATE PROC [dbo].[CustomPaged] @tablename NVARCHAR(100) = NULL ,--所要查詢的表或視圖名 不可以設置表別名 表名在關系表中設置 tablename a @nexusStr NVARCHAR(1000) = '' ,--關系表 left join tablename b on a.columnname=b.columnname @columnsName NVARCHAR(1000) = '*' ,--查詢所需的列名 @rankOrder NVARCHAR(2000) = '' ,--流水號排序列以及方式 @currentIndex INT = 1 ,--頁碼 按正常頁面寫參數就可以了 @pagesize INT = 10 ,--每頁的行數量 @where NVARCHAR(2000) = '' ,--查詢條件 @order NVARCHAR(2000) = '' ,--排序列 @AllCount INT OUTPUT--jieguohang AS BEGIN IF ( ISNULL(@tablename, '') != '' ) BEGIN SET nocount ON; DECLARE @tempTableName VARCHAR(1000); SELECT @tempTableName = '[##' + RTRIM(LTRIM(REPLACE(hostname, '-', '_'))) + '_' + RTRIM(LTRIM(net_address)) + '_' + dbo.regexReplace(@tablename, '[^\w]', '_', 0, 0) + '_' + CAST(@@SPID AS VARCHAR(10)) + ']' FROM master..sysprocesses WHERE spid = @@SPID IF ( ISNULL(@columnsName, '') = '' ) SET @columnsName = '*'; IF ( ISNULL(@rankorder, '') = '' ) BEGIN --判斷該表是否存在主鍵 IF EXISTS ( SELECT keyno FROM sysindexkeys WHERE id = OBJECT_ID(@tablename) ) BEGIN SELECT @rankorder = name FROM SysColumns WHERE id = OBJECT_ID(@tablename) AND colid = ( SELECT TOP 1 keyno FROM sysindexkeys WHERE id = OBJECT_ID(@tablename) ) END ELSE BEGIN SELECT TOP 1 @rankorder = name FROM SysColumns WHERE id = OBJECT_ID(@tablename) END END DECLARE @sql NVARCHAR(2000) SET @sql = 'select row_number() over(order by ' + @rankOrder + ') as rankid,' + @columnsName + ' into ' + @tempTableName + ' from ' + @tablename; IF ( ISNULL(@nexusStr, '') != '' ) SET @sql = @sql + ' ' + @nexusStr; --添加查詢條件 IF ( LEN(@where) > 0 ) BEGIN SET @sql = @sql + ' where ' + @where; END --添加排序列 IF ( LEN(@order) > 0 ) BEGIN SET @sql = @sql + ' order by ' + @order END --動態執行sql語句 EXEC(@sql); DECLARE @totality INT; SET @sql = 'select @total=COUNT(*) from ' + @tempTableName; EXEC sp_executesql @sql, N'@total int output', @totality OUTPUT; --驗證當查詢的前頁是否超出查詢的頁,超過則返回查詢也的第一頁 DECLARE @IsHavePage BIT; IF ( @totality % @pagesize > 0 ) SET @IsHavePage = 1; ELSE SET @IsHavePage = 0; IF @totality / @pagesize + CAST(@IsHavePage AS INT) < @currentIndex--當前總頁數/每頁顯示數 SET @currentIndex = 1; ELSE --在排序頁中的頁碼索引應該從0開始為第一頁 SET @currentIndex = @currentIndex - 1; SET @sql = 'select * from ' + @tempTableName + ' where rankid>' + CONVERT(VARCHAR(10), @currentIndex * @pagesize) + ' and rankid<=' + CONVERT(VARCHAR(10), @currentIndex * @pagesize + @pagesize); SET @sql = @sql + ';drop table ' + @tempTableName; EXEC(@sql); SET nocount OFF; SET @AllCount = ISNULL(@totality, 0); END END GO
在調用上面的存儲過程之前,必須先在數據庫中執行以下方法
--正則替換 --開啟xp_cmdshell --不開啟會提示:SQL Server blocked access to procedure 'xp_cmdshell' go sp_configure 'show advanced options', 1 go reconfigure go sp_configure 'xp_cmdshell', 1 go reconfigure --開啟sp_OACreate --不開啟會提示:SQL Server blocked access to procedure 'sys.sp_OACreate' go sp_configure 'show advanced options', 1; go reconfigure; go sp_configure 'ole automation procedures', 1; go reconfigure; go drop function [regexReplace] go --創建函數 create function [dbo].[regexReplace] ( @source varchar(8000), --字符串 @regexp varchar(500), --正則表換式 @replace varchar(500), --替換值 @globalReplace bit = 0, --是否是全局替換 @ignoreCase bit = 0 --是否忽略大小寫 ) returns varchar(1000) AS begin declare @hr int declare @objRegExp int declare @result varchar(5000) exec @hr = sp_OACreate 'VBScript.RegExp', @objRegExp output if @hr <> 0 begin exec @hr = sp_OADestroy @objRegExp return null end exec @hr = sp_OASetProperty @objRegExp, 'Pattern', @regexp if @hr <> 0 begin exec @hr = sp_OADestroy @objRegExp return null end exec @hr = sp_OASetProperty @objRegExp, 'Global', @globalReplace if @hr <> 0 begin exec @hr = sp_OADestroy @objRegExp return null end exec @hr = sp_OASetProperty @objRegExp, 'IgnoreCase', @ignoreCase if @hr <> 0 begin exec @hr = sp_OADestroy @objRegExp return null end exec @hr = sp_OAMethod @objRegExp, 'Replace', @result output, @source, @replace if @hr <> 0 begin exec @hr = sp_OADestroy @objRegExp return null end exec @hr = sp_OADestroy @objRegExp if @hr <> 0 begin return null end /* 注釋A -- while (charindex('..',@result)<>0) -- begin -- set @result=replace(@result,'..','.') -- end -- if(left(@result,1)='.') -- set @result=right(@result,len(@result)-1) -- if(right(@result,1)='.') -- set @result=left(@result,len(@result)-1) */ return @result end
大功告成
