實作一個通用的分頁預存程序 p_show,支援:
TOP 優化效能| 參數 | 型別 | 預設值 | 說明 |
|---|---|---|---|
| @QueryStr | nvarchar(4000) | - | 資料表名、檢視表名或完整 SELECT 陳述式 |
| @PageSize | int | 10 | 每頁筆數 |
| @PageCurrent | int | 1 | 要顯示的頁碼 |
| @FdShow | nvarchar(4000) | '' | 要顯示的欄位清單,若有身分欄位需指定且不含身分欄位 |
| @FdOrder | nvarchar(1000) | '' | 排序欄位清單 |
SELECT TOP @PageSize ... 快速回傳。object_id() 判斷 @QueryStr 是否為資料表物件。
status=0x80)xtype='PK')NOT IN (SELECT TOP ...) 分頁LEFT JOIN 排除前 N 筆IDENTITY 欄位的暫存表 #tb,依排序匯入資料,再依身分值範圍篩選頁面資料。select @strfd='', @strjoin='', @strwhere=''
select @strfd=@strfd+',['+name+']'
,@strjoin=@strjoin+' and a.['+name+']=b.['+name+']'
,@strwhere=@strwhere+' and b.['+name+'] is null'
from syscolumns where id=@Obj_ID and colid in (...)
select @strfd=substring(@strfd,2,2000)
,@strjoin=substring(@strjoin,5,4000)
,@strwhere=substring(@strwhere,5,4000)
-- 動態 SQL
exec('select '+@FdShow+' from (select top '+@Id1+' a.* from
(select top 100 percent * from '+@QueryStr+@FdOrder+') a
left join (select top '+@Id2+' '+@strfd+' from '+@QueryStr+@FdOrder+') b on '+@strjoin+'
where '+@strwhere+') a')
select @FdName='[ID_'+cast(newid() as varchar(40))+']'
,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20))
,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20))
exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'
into #tb from '+@QueryStr+@FdOrder)
exec('select '+@FdShow+' from #tb where '+@FdName+' between '+@Id1+' and '+@Id2)
-- 查詢資料表前 3 頁,每頁 5 筆
exec p_show '地區資料', 5, 3, '地區編號,地區名稱,助記碼', '地區編號'
-- 查詢排序後的檢視表/子查詢 (需加 top 100 percent)
exec p_show 'select top 100 percent * from 地區資料 order by 地區名稱', 5, 3, '地區編號,地區名稱,助記碼', '地區名稱'
ORDER BY 的子查詢必須加上 TOP 100 PERCENT 才能正確排序。EXEC() 執行,需防範 SQL 注入,確保輸入參數來源可信。