5

我有一个存储过程,它使用外连接和 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
4

3 回答 3

7

将选项与CTEOVER()子句一起使用

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)
于 2013-03-28T08:19:31.620 回答
1

您可以阅读以下论文:

SQL Server 存储过程对大型表或查询进行分页

或者

具有排序、分页和过滤的存储过程

于 2014-07-31T02:51:15.647 回答
1

旧方法 - 带有(限制、订单方向、订单列、开始索引)的简单分页脚本

@orderColumn  int ,
@orderDir  varchar(20),
@start  int ,
@limit  int,
@searchKey varchar(20)

declare @to as int = @start+@limit

select IDENTITY(int, 1, 1) AS SnoID,null as abc, make.link,make.manf,make.name
into #tempMake
 from make where status=1 and UPPER(make.name) like upper('%'+@searchKey+'%')


select * from #tempMake where SnoID>@start and SnoID<=@to
    order by               
                CASE WHEN @orderColumn = 1 AND @orderdir = 'desc' THEN #tempMake.[manf] END DESC,
                CASE WHEN @orderColumn = 1 AND @orderdir = 'asc' THEN #tempMake.[manf] END ASC,
                CASE WHEN @orderColumn = 2 AND @orderdir = 'desc' THEN #tempMake.[link] END DESC,
                CASE WHEN @orderColumn = 2 AND @orderdir = 'asc' THEN #tempMake.[link] END ASC

select count(#tempMake.SnoID) as row_count from #tempMake 

drop table #tempMake
于 2016-01-02T09:10:53.117 回答