替代SQL Server中的偏移量

时间:2018-06-28 06:11:17

标签: sql-server sql-server-2008 stored-procedures offset

我在sql server 2016中具有以下存储过程,在那儿工作正常。

现在我需要在sql 2008中创建相同的sp,现在出现错误:

  

Msg 102,第15级,状态1,过程GetEmployees,第41行[批处理   起始行0] “ OFFSET”附近的语法不正确。 153号讯息,州立15级   2,过程GetEmployees,第42行[Batch Start Line 0]用法无效   FETCH语句中选项NEXT的选项。

如何修改相同的proc,以便它也可以在sql 2008上运行。

 --dbo.GetEmployees '',2,2  
    CreatePROCEDURE [dbo].GetEmployees    
    (    
     @SearchValue NVARCHAR(50) = '',    
     @PageNo INT = 0,    
     @PageSize INT = 10,    
     @SortColumn NVARCHAR(20) = 'Name',    
     @SortOrder NVARCHAR(20) = 'ASC'    
    )    
     AS BEGIN    
     SET NOCOUNT ON;    
     if @PageNo<0 set @PageNo=0   
     set @PageNo=@PageNo+1  
     SET @SearchValue = LTRIM(RTRIM(@SearchValue))    
     Set @SearchValue= nullif(@SearchValue,'')    
     ; WITH CTE_Results AS     
    (    
        SELECT EmployeeID, Name, City from tblEmployee     
     WHERE (@SearchValue IS NULL OR Name LIKE '%' + @SearchValue + '%')     
           ORDER BY    
      CASE WHEN (@SortColumn = 'EmployeeID' AND @SortOrder='ASC')    
                        THEN EmployeeID    
            END ASC,    
            CASE WHEN (@SortColumn = 'EmployeeID' AND @SortOrder='DESC')    
                       THEN EmployeeID    
           END DESC,    

         CASE WHEN (@SortColumn = 'Name' AND @SortOrder='ASC')    
                        THEN Name    
            END ASC,    
            CASE WHEN (@SortColumn = 'Name' AND @SortOrder='DESC')    
                       THEN Name    
      END DESC,    

      CASE WHEN (@SortColumn = 'City' AND @SortOrder='ASC')    
                        THEN City    
            END ASC,    
            CASE WHEN (@SortColumn = 'City' AND @SortOrder='DESC')    
                       THEN City    
      END DESC     
          OFFSET @PageSize * (@PageNo - 1) ROWS    
          FETCH NEXT @PageSize ROWS ONLY    
     ),    
    CTE_TotalRows AS     
    (    
     select count(EmployeeID) as MaxRows from tblEmployee WHERE (@SearchValue IS NULL OR Name LIKE '%' + @SearchValue + '%')    
    )    
       Select MaxRows TotalRecords, t.EmployeeID, t.Name, t.City,t.Department,t.Gender from dbo.tblEmployee as t, CTE_TotalRows     
       WHERE EXISTS (SELECT 1 FROM CTE_Results WHERE CTE_Results.EmployeeID = t.EmployeeID)    
       OPTION (RECOMPILE)    
       END 

2 个答案:

答案 0 :(得分:1)

您需要一个row_number()窗口函数,并且需要在OVER部分中放置整个排序表达式。请注意,出于可读性的考虑,我创建了另一个CTE,但是仅通过子查询就可以完成相同的工作。

SELECT语句的格式化代码如下:

WITH CTE_Rownums AS (
  SELECT 
    EmployeeID, 
    Name, 
    City,
    row_number() over ( ORDER BY ... ) as rn -- put your entire order by here
  FROM tblEmployee     
  WHERE 
    @SearchValue IS NULL 
    OR Name LIKE '%' + @SearchValue + '%'
), CTE_Results AS (    
  SELECT EmployeeID, Name, City
  FROM CTE_Rownums
  WHERE 
    (rn > @PageSize * (@PageNo - 1)
    AND (rn <= @PageSize * @PageNo)
  ORDER BY rn   
 ), CTE_TotalRows AS (    
  SELECT count(EmployeeID) as MaxRows
  FROM tblEmployee 
  WHERE 
  @SearchValue IS NULL 
  OR Name LIKE '%' + @SearchValue + '%'
)
SELECT MaxRows TotalRecords, t.EmployeeID, t.Name, t.City,t.Department,t.Gender
FROM dbo.tblEmployee as t
CROSS JOIN CTE_TotalRows     
WHERE EXISTS (
  SELECT 1 
  FROM CTE_Results
  WHERE CTE_Results.EmployeeID = t.EmployeeID
)    
OPTION (RECOMPILE)

在上一个SELECT中,我用CROSS JOIN替换了逗号分隔的where子句。

答案 1 :(得分:1)

如果您使用 2008 R2 或更早版本,则不能使用 OFFSET FETCH

您可以选择使用 ROW_NUMBER() 并重写您的查询,例如

带有OFFSET

SELECT Price
FROM dbo.Inventory
ORDER BY Price OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY

这个没有使用 OFFSET 的查询使用 ROW_NUMBER()

SELECT Price
FROM
(
SELECT Price
ROW_NUMBER() OVER (ORDER BY Price) AS Seq
FROM dbo.Inventory
)t
WHERE Seq BETWEEN 11 AND 15