激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - asp.net 分頁存儲過程實例剖析心得

asp.net 分頁存儲過程實例剖析心得

2019-09-20 14:04asp.net教程網 ASP.NET教程

最近修改了個分頁存儲過程,作為菜鳥,還是從中獲益良多,這里就開始今天的分頁之旅了

1.開始還原 下面先看一下原來的分頁存儲過程。 

復制代碼代碼如下:


ALTER PROCEDURE [dbo].[sp_Sql_Paging] 

@SqlDataTable NVARCHAR(4000), -- 表名 
@PrimaryKey NVARCHAR(4000), -- 主鍵名稱 
@Fields NVARCHAR(4000), -- 要返回的字段 
@pageSize INT, -- 頁尺寸 
@pageIndex INT, -- 頁碼 
@recordCount INT OUTPUT, -- 記錄總數 
@strOrderBy NVARCHAR(4000), -- 排序 
@strWhere NVARCHAR(4000) -- 查詢條件 

AS 
BEGIN 
SET NOCOUNT ON 
DECLARE @strSQL1 NVARCHAR(4000) -- SQL語句1 
DECLARE @strSQL2 NVARCHAR(4000) -- SQL語句2 

-- 創建臨時表 
-- 用來保存表的編號以及主鍵 
CREATE TABLE #Temp_Paging 

Temp_Paging_Id INT, 
RowNumber INT 

SET @strSQL1 = 'INSERT INTO [#Temp_Paging](Temp_Paging_Id, RowNumber) SELECT ' + @PrimaryKey + ', ROW_NUMBER() OVER (' + @strOrderBy + ') AS RowNumber FROM ' + @SqlDataTable + ' ' + @strWhere 
EXEC SP_EXECUTESQL @strSQL1 
SET @recordCount = @@ROWCOUNT -- 取得總記錄數 

-- 判斷頁索引 
IF @pageIndex > @recordCount * 1.0 / @pageSize + 1.0 OR @recordCount <= @pageSize 
BEGIN 
SET @pageIndex = 1 
END 

-- 分頁查詢 
SET @strSQL2 = 'SELECT ' + @Fields + ' FROM ' + @SqlDataTable + ' WHERE ' + @PrimaryKey + ' IN (SELECT Temp_Paging_Id FROM [#Temp_Paging] WHERE RowNumber BETWEEN ' + Str((@pageIndex - 1) * @pageSize + 1) + ' AND ' + Str(@pageIndex * @pageSize) + ') ' + @strOrderBy 
EXEC SP_EXECUTESQL @strSQL2 
DROP TABLE #Temp_Paging -- 刪除臨時表 
END 


從原分頁存儲過程很容易看出,這里運用了臨時表保存編號,然后在通過pageIndex和pageSize計算所得,進行分頁。 

因為這里還以主鍵作為查詢條件,故臨時表中也保存了主鍵值。 

很顯然,這里的臨時表無法做到通用,因為主鍵的類型不一定是上面定義的INT型,也可以是其它的類型,比如:uniqueidentifier(全球唯一標識)。 

這樣的話,這個存儲過程就碰到了問題,所以必須進行改進。 

2.思路一 
思路一很簡單,那就把這個類型聲明成一個變量,然后通過系統表獲取表的主鍵類型,再賦給變量不就可以了嗎??雌饋砗苊烂睿环猎囈辉囅?。 

我們可以插入下面一段代碼: 

復制代碼代碼如下:


DECLARE @colType NVARCHAR(50) --主鍵列類型 
DECLARE @strSQL3 NVARCHAR(500) --創建臨時表語句 

SET @colType = (SELECT typ.name as 數據類型 
FROM sys.columns col 
left join sys.types typ 
on (col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id) 
WHERE col.object_id = (SELECT object_id FROM sys.tables WHERE name = @SqlDataTable) 
and exists 
( SELECT 1 FROM sys.indexes idx 
join sys.index_columns idxCol 
on (idx.object_id = idxCol.object_id) 
WHERE idx.object_id = col.object_id 
AND idxCol.index_column_id = col.column_id 
AND idx.is_primary_key = 1 
)) 

SET @strSQL3 = 'CREATE TABLE #Temp_Paging 

Temp_Paging_Id '+ @colType+', 
RowNumber INT 
)' 
PRINT @strSQL3 
--EXEC(@strSQL3) 


打印結果: 

復制代碼代碼如下:


CREATE TABLE #Temp_Paging 

Temp_Paging_Id uniqueidentifier, 
RowNumber INT 


很顯然我們得到了所需要的臨時表。這時我很開心,因為得到了我想要的東西。但似乎還沒有結束,我要執行下該存儲過程。 

壞結果往往在這時出現: asp.net 分頁存儲過程實例剖析心得
這里就出現奇怪的事了,按打印出來的明明是正確的創建臨時表語句,而且也執行了,為什么接下來對臨時表的操作又是無效的了? 

找資料問同事,終于明白,原來臨時表分本地臨時表和全局臨時表。本地臨時表需要注意實際刪除的時間。 

這里說得簡單一點:當在用EXEC(@strSQL3) 創建臨時表的時候,同時已經刪除了臨時表。因為EXEC這個過程的會話已經結束,臨時表就被刪除了。 

這里有一篇博文做了更具體的解釋,大家可以參考:點滴在心頭_SQL臨時表 

3.思路二 

上面的思路似乎行不通,那不如再換個思路,干脆不要建立臨時表,用Select * from (select * from table) as temptable 這種思路代替創建臨時表。 

代碼如下: 

復制代碼代碼如下:


ALTER PROCEDURE [dbo].[sp_Sql_Paging] 

@SqlDataTable NVARCHAR(4000), -- 表名 
@PrimaryKey NVARCHAR(4000), -- 主鍵名稱 
@Fields NVARCHAR(4000), -- 要返回的字段 
@pageSize INT, -- 頁尺寸 
@pageIndex INT, -- 頁碼 
@recordCount INT OUTPUT, -- 記錄總數 
@strOrderBy NVARCHAR(4000), -- 排序 
@strWhere NVARCHAR(4000) -- 查詢條件 

AS 
BEGIN 
SET NOCOUNT ON 
DECLARE @strSQL1 NVARCHAR(4000) -- SQL語句1 
DECLARE @strSQL2 NVARCHAR(4000) -- SQL語句2 
DECLARE @strSQL3 NVARCHAR(4000) -- SQL語句3 

SET @strSQL1 = 'SELECT ' + @PrimaryKey + ', ROW_NUMBER() OVER (' + @strOrderBy + ') AS RowNumber FROM ' + @SqlDataTable + ' ' + @strWhere 

--獲取總記錄數 
SET @strSQL3 = 'SELECT @recordCount = COUNT(*) FROM ' + @SqlDataTable + ' ' + @strWhere 
EXEC SP_EXECUTESQL 
@stmt = @strSQL3, 
@params = N'@recordCount AS INT OUTPUT', 
@recordCount = @recordCount OUTPUT 

--分頁查詢 
IF @pageIndex > @recordCount * 1.0 / @pageSize + 1.0 OR @recordCount <= @pageSize 
BEGIN 
SET @pageIndex = 1 
END 
SET @strSQL2 = 'SELECT ' + @Fields + ' FROM ' + @SqlDataTable + ' WHERE ' + @PrimaryKey + ' IN (SELECT '+@PrimaryKey+' FROM ('+@strSQL1+') TempTable WHERE RowNumber BETWEEN ' + Str((@pageIndex - 1) * @pageSize + 1) + ' AND ' + Str(@pageIndex * @pageSize) + ') ' + @strOrderBy 
EXEC SP_EXECUTESQL @strSQL2 
END 


這里有個小知識點,注意EXEC SP_EXECUTESQL的寫法以及和EXEC(@strsql)的區別。大家可以去找資料了解下。 

關于分頁的一些事就寫到這了,僅供參考。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: www国产成人免费观看视频 | 国产成人精品一区二区仙踪林 | 国产精品99久久久久久久女警 | 国av在线 | 欧美黄色免费视频 | 成人一级片毛片 | 男男啪羞羞视频网站 | 黄色特级 | 91看片网页版| 水卜樱一区二区av | 欧美三级欧美成人高清www | 国产亚洲精品综合一区91555 | 国产激情精品一区二区三区 | 国产一级在线免费观看 | 国产精品啪一品二区三区粉嫩 | 精品国产三级a | 19禁国产精品福利视频 | 欧美精品一区二区蜜臀亚洲 | 黄色av网站在线观看 | 亚洲成人黄色片 | 精品国产91久久久 | 视频一区二区三区在线观看 | 羞羞网站 | 一级在线视频 | 久久久久亚洲视频 | 草草视频免费 | 一级国产精品一级国产精品片 | 一级毛片手机在线观看 | 欧美日韩亚洲一区二区三区 | 叉逼视频 | 国产大片在线观看 | 天海翼无删减av三级在线观看 | 国产精品久久久久久久久久10秀 | 欧美精品一区二区视频 | 91看片在线观看视频 | 一级欧美日韩 | 羞羞答答xxdd在线播放 | 中文字幕欧美视频 | 在线免费日本 | julieann艳星激情办公室 | 日韩剧情片 |