sql - 使用sql server存储过程对记录进行分页

标签 sql sql-server sql-server-2008 tsql

我有一个存储过程,它使用外连接和 where 条件从两个表返回结果。它也有 order by 子句。我想为其添加分页,以便仅返回请求的记录数。我该怎么做?我需要提供页码、记录总数、当前页等?我的存储过程是:

CREATE PROCEDURE [dbo].[hr_SearchVacanciesForService]

    @SearchText NVARCHAR(50) = NULL,
    @DutyStationID INT = NULL,
    @VacancyCategoryIDs VARCHAR(1000) = NULL,
    @Language INT = 1
AS

SELECT *
FROM dbo.hr_Vacancies LEFT OUTER JOIN dbo.hr_DutyStations ON dbo.hr_Vacancies.DutyStationID = dbo.hr_DutyStations.DutyStationID 
    LEFT OUTER JOIN dbo.hr_Companies    
        ON dbo.hr_Vacancies.CompanyID = dbo.hr_Companies.CompanyID 
WHERE dbo.hr_Vacancies.Deleted = 0 
        AND (dbo.hr_Vacancies.JobTitleLang1 LIKE @LoacalSeacrchText 
        OR dbo.hr_Vacancies.JobTitleLang2 LIKE @LoacalSeacrchText 
        OR dbo.hr_Vacancies.DescriptionLang1 LIKE @LoacalSeacrchText 
        OR dbo.hr_Vacancies.DescriptionLang2 LIKE @LoacalSeacrchText    
    AND (dbo.hr_Vacancies.DutyStationID = @DutyStationID OR @DutyStationID IS NULL OR @DutyStationID = 0)
    ORDER BY HavePriority DESC, StartDate DESC, dbo.hr_Vacancies.VacancyID DESC

最佳答案

使用 CTE 选项和 OVER()条款

CREATE PROCEDURE [dbo].[hr_SearchVacanciesForService]
@SearchText NVARCHAR(50) = NULL,
@DutyStationID INT = NULL,
@VacancyCategoryIDs VARCHAR(1000) = NULL,
@Language INT = 1,
@NumberOfPages int
AS
;WITH cte AS
 (
  SELECT *, ROW_NUMBER() OVER (ORDER BY HavePriority DESC, StartDate DESC, dbo.hr_Vacancies.VacancyID DESC) AS Pages
  FROM dbo.hr_Vacancies LEFT OUTER JOIN dbo.hr_DutyStations ON dbo.hr_Vacancies.DutyStationID = dbo.hr_DutyStations.DutyStationID 
                        LEFT OUTER JOIN dbo.hr_Companies ON dbo.hr_Vacancies.CompanyID = dbo.hr_Companies.CompanyID 
  WHERE dbo.hr_Vacancies.Deleted = 0 
    AND (dbo.hr_Vacancies.JobTitleLang1 LIKE @LoacalSeacrchText 
    OR dbo.hr_Vacancies.JobTitleLang2 LIKE @LoacalSeacrchText 
    OR dbo.hr_Vacancies.DescriptionLang1 LIKE @LoacalSeacrchText 
    OR dbo.hr_Vacancies.DescriptionLang2 LIKE @LoacalSeacrchText    
    AND (dbo.hr_Vacancies.DutyStationID = @DutyStationID OR @DutyStationID IS NULL OR @DutyStationID = 0)
  )
  SELECT *, COUNT(*) OVER() AS totalOfPages
  FROM cte
  WHERE Pages BETWEEN 1 AND ISNULL(@NumberOfPages, Pages)

使用带有表达式的 OVER() 子句的示例:

SELECT ... ROW_NUMBER() OVER (ORDER BY
CASE WHEN dbo.hr_Vacancies.Priority = 0 
     THEN 0 ELSE 
CASE WHEN CONVERT(DATETIME,CONVERT(CHAR(10),dbo.hr_Vacancies.PriorityDateExpired,101)) > CONVERT(DATETIME,CONVERT(CHAR(10),GETDATE(),101)) OR dbo.hr_Vacancies.PriorityDateExpired IS NULL 
     THEN 1 ELSE 0 END END DESC, your_second_expression_StartDate DESC) 

如果要显示 20 到 30 条记录:

CREATE PROCEDURE [dbo].[hr_SearchVacanciesForService]

    @SearchText NVARCHAR(50) = NULL,
    @DutyStationID INT = NULL,
    @VacancyCategoryIDs VARCHAR(1000) = NULL,
    @Language INT = 1,
    @StartPage int = NULL,
    @EndPage int = NULL
AS
;WITH cte AS
 (
  SELECT *, ROW_NUMBER() OVER (ORDER BY your_case_expressionForColumnHavePriority DESC, your_case_expressionForColumnStartDate DESC, dbo.hr_Vacancies.VacancyID DESC) AS Pages
  FROM dbo.hr_Vacancies LEFT OUTER JOIN dbo.hr_DutyStations ON dbo.hr_Vacancies.DutyStationID = dbo.hr_DutyStations.DutyStationID 
                        LEFT OUTER JOIN dbo.hr_Companies ON dbo.hr_Vacancies.CompanyID = dbo.hr_Companies.CompanyID 
  WHERE dbo.hr_Vacancies.Deleted = 0 
          AND (dbo.hr_Vacancies.JobTitleLang1 LIKE @LoacalSeacrchText 
          OR dbo.hr_Vacancies.JobTitleLang2 LIKE @LoacalSeacrchText 
          OR dbo.hr_Vacancies.DescriptionLang1 LIKE @LoacalSeacrchText 
          OR dbo.hr_Vacancies.DescriptionLang2 LIKE @LoacalSeacrchText    
      AND (dbo.hr_Vacancies.DutyStationID = @DutyStationID OR @DutyStationID IS NULL OR @DutyStationID = 0)
  )
  SELECT *, COUNT(*) OVER() AS totalOfPages
  FROM cte
  WHERE Pages BETWEEN ISNULL(@StartPage, Pages) AND ISNULL(@EndPage, Pages)

关于sql - 使用sql server存储过程对记录进行分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15676685/

相关文章:

mysql - 在 MySQL 的查询中创建 Select 查询

mysql - 在十字路口 : Choice Between MySQL vs MSSQL -> Importance: Reporting

sql - CASE vs IF-ELSE-IF vs GOTO 关键字

sql-server - 将数据插入到表中,其中表名称是动态的?

php - MySQL,其中 SUM(value) 大于 UNION 查询中的特定值

mysql - 如何从名为 Employee 的表中获取记录,其中外键名为 ManagerId 引用本身 empId

sql - 复制 Azure SQL 数据库并更改规模

c# - 在表更新时,在我的 .NET 代码中触发一个操作

asp.net - 获取在触发器 SQL Server 2008 中插入或更新的当前成员资格用户

sql - 在 SQL Server 2008 中执行空集时强制 SVG 返回 0 而不是 NULL