首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 分頁預存程序通用實作:支援任意查詢與排序

     編輯:關於SqlServer

功能特性

  • 支援資料表、檢視表、任意查詢語句做為資料來源。
  • 有主鍵/識別欄位時直接查詢原表;否則使用暫存表機制。
  • 針對帶排序查詢有特定語法要求(需加 TOP 100 PERCENT)。

呼叫範例

-- 簡單呼叫(預設每頁10筆,第1頁)
EXEC p_show '地區資料'

-- 完整參數:資料來源、頁面大小、目前頁碼、顯示欄位、排序欄位
EXEC p_show '地區資料', 5, 3, '地區編號,地區名稱,助記碼', '地區編號'

-- 複雜查詢(需加 TOP 100 PERCENT 確保排序生效)
EXEC p_show 'SELECT TOP 100 PERCENT * FROM 地區資料 ORDER BY 地區名稱', 5, 3, '地區編號,地區名稱,助記碼', '地區名稱'

預存程序核心程式碼

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[p_show]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
    DROP PROCEDURE [dbo].[p_show]
GO

CREATE PROC p_show
    @QueryStr NVARCHAR(4000),      -- 表名、視圖名、查詢語句
    @PageSize INT = 10,            -- 每頁筆數
    @PageCurrent INT = 1,          -- 目標頁碼
    @FdShow NVARCHAR(4000) = '',   -- 顯示欄位清單(若有識別欄位需指定,不含識別欄位)
    @FdOrder NVARCHAR(1000) = ''   -- 排序欄位清單
AS
    DECLARE @FdName NVARCHAR(250)  -- 主鍵或識別欄位名
    DECLARE @Id1 VARCHAR(20), @Id2 VARCHAR(20)  -- 起始/結束記錄號
    DECLARE @Obj_ID INT            -- 物件 ID
    -- 複合主鍵處理變數
    DECLARE @strfd NVARCHAR(2000), @strjoin NVARCHAR(4000), @strwhere NVARCHAR(2000)

    SELECT @Obj_ID = OBJECT_ID(@QueryStr),
           @FdShow = CASE ISNULL(@FdShow, '') WHEN '' THEN ' *' ELSE ' ' + @FdShow END,
           @FdOrder = CASE ISNULL(@FdOrder, '') WHEN '' THEN '' ELSE ' ORDER BY ' + @FdOrder END,
           @QueryStr = CASE WHEN @Obj_ID IS NOT NULL THEN ' ' + @QueryStr ELSE ' (' + @QueryStr + ') a' END

    -- 第 1 頁直接用 TOP
    IF @PageCurrent = 1
    BEGIN
        SELECT @Id1 = CAST(@PageSize AS VARCHAR(20))
        EXEC('SELECT TOP ' + @Id1 + @FdShow + ' FROM ' + @QueryStr + @FdOrder)
        RETURN
    END

    -- 若為資料表,檢查識別欄位或主鍵
    IF @Obj_ID IS NOT NULL AND OBJECTPROPERTY(@Obj_ID, 'IsTable') = 1
    BEGIN
        SELECT @Id1 = CAST(@PageSize AS VARCHAR(20)),
               @Id2 = CAST((@PageCurrent - 1) * @PageSize AS VARCHAR(20))

        SELECT @FdName = NAME FROM syscolumns WHERE id = @Obj_ID AND status = 0x80
        IF @@ROWCOUNT = 0  -- 無識別欄位
        BEGIN
            IF NOT EXISTS (SELECT 1 FROM sysobjects WHERE parent_obj = @Obj_ID AND xtype = 'PK')
                GOTO lbusetemp  -- 無主鍵,改用暫存表
        END
        -- ... 後續邏輯處理單一主鍵、複合主鍵、暫存表分頁 ...
    END
    -- ... 視圖與查詢語句統一使用暫存表分頁 ...

設計重點說明

  1. 動態 SQL 執行:使用 EXEC('...') 執行組裝完成的查詢字串。
  2. 識別欄位偵測:查詢 syscolumns.status = 0x80 判斷 IDENTITY 欄位。
  3. 主鍵偵測:查詢 sysobjects.xtype = 'PK' 判斷 PRIMARY KEY。
  4. 複合主鍵處理:建立動態 JOIN 條件與 WHERE 子句。
  5. 暫存表備援:無主鍵/識別欄位時,將查詢結果導入暫存表加識別欄位後分頁。
  6. 排序查詢要求:外部傳入的查詢若含 ORDER BY,必須加 TOP 100 PERCENT 才能在子查詢中保留排序。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved