分頁預存程序執行個體剖析心得(1)

來源:互聯網
上載者:User

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

1.開始還原

下面先看一下原來的分頁預存程序。

 
  1. ALTER PROCEDURE [dbo].[sp_Sql_Paging] 
  2.     @SqlDataTable        NVARCHAR(4000),        -- 表名 
  3.     @PrimaryKey            NVARCHAR(4000),        -- 主鍵名稱 
  4.     @Fields                NVARCHAR(4000),        -- 要返回的欄位 
  5.     @pageSize            INT,                -- 頁尺寸 
  6.     @pageIndex            INT,                -- 頁碼 
  7.     @recordCount        INT    OUTPUT,            -- 記錄總數 
  8.     @strOrderBy            NVARCHAR(4000),        -- 排序 
  9.     @strWhere            NVARCHAR(4000)        -- 查詢條件 
  10. AS 
  11. BEGIN 
  12.     SET NOCOUNT ON 
  13.     DECLARE @strSQL1    NVARCHAR(4000)        -- SQL語句1 
  14.     DECLARE @strSQL2    NVARCHAR(4000)        -- SQL語句2 
  15.  
  16.     -- 建立暫存資料表 
  17.     -- 用來儲存表的編號以及主鍵 
  18.     CREATE TABLE #Temp_Paging 
  19.     ( 
  20.         Temp_Paging_Id INT, 
  21.         RowNumber INT 
  22.     ) 
  23.     SET @strSQL1 = 'INSERT INTO [#Temp_Paging](Temp_Paging_Id, RowNumber) SELECT ' + @PrimaryKey + ', ROW_NUMBER() OVER (' + @strOrderBy + ') AS RowNumber FROM ' + @SqlDataTable + ' ' + @strWhere  
  24.     EXEC SP_EXECUTESQL @strSQL1 
  25.     SET @recordCount = @@ROWCOUNT -- 取得總記錄數 
  26.       
  27.     -- 判斷頁索引 
  28.     IF @pageIndex > @recordCount * 1.0 / @pageSize + 1.0 OR @recordCount <= @pageSize 
  29.         BEGIN 
  30.             SET @pageIndex = 1 
  31.         END 
  32.       
  33.     -- 分頁查詢 
  34.     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 
  35.     EXEC SP_EXECUTESQL @strSQL2 
  36.     DROP TABLE #Temp_Paging -- 刪除暫存資料表 
  37. END 

從原分頁預存程序很容易看出,這裡運用了暫存資料表儲存編號,然後在通過pageIndex和pageSize計算所得,進行分頁。

因為這裡還以主鍵作為查詢條件,故暫存資料表中也儲存了主索引值。

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

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

2.思路一

思路一很簡單,那就把這個型別宣告成一個變數,然後通過系統資料表擷取表的主鍵類型,再賦給變數不就可以了嗎。看起來很美妙,不妨試一試先。

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

 
  1. DECLARE @colType NVARCHAR(50)  --主鍵列類型 
  2. DECLARE @strSQL3 NVARCHAR(500) --建立暫存資料表語句 
  3.  
  4. SET @colType = (SELECT typ.name as 資料類型 
  5.                 FROM sys.columns col  
  6.                 left join sys.types typ  
  7.                 on (col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id) 
  8.                 WHERE col.object_id = (SELECT object_id FROM sys.tables WHERE name = @SqlDataTable) 
  9.                 and exists  
  10.                 ( SELECT 1 FROM sys.indexes idx  
  11.                     join sys.index_columns idxCol  
  12.                       on (idx.object_id = idxCol.object_id) 
  13.                     WHERE idx.object_id = col.object_id 
  14.                       AND idxCol.index_column_id = col.column_id  
  15.                       AND idx.is_primary_key = 1 
  16.                 )) 
  17.  
  18. SET @strSQL3 = 'CREATE TABLE #Temp_Paging 
  19.                 ( 
  20.                     Temp_Paging_Id '+ @colType+', 
  21.                     RowNumber INT  
  22.                 )' 
  23. PRINT @strSQL3 
  24. --EXEC(@strSQL3) 

列印結果:

 
  1. CREATE TABLE #Temp_Paging 
  2.                 ( 
  3.                     Temp_Paging_Id uniqueidentifier, 
  4.                     RowNumber INT  
  5.                 ) 

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

壞結果往往在這時出現:

這裡就出現奇怪的事了,按列印出來的明明是正確的建立暫存資料表語句,而且也執行了,為什麼接下來對暫存資料表的操作又是無效的了?

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

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

這裡有一篇博文做了更具體的解釋,大家可以參考:點滴在心頭_SQL暫存資料表


相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.