【问题标题】:Alternate of offset in sql serversql server中偏移量的替代
【发布时间】:2018-06-28 06:11:16
【问题描述】:

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

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

Msg 102,级别 15,状态 1,过程 GetEmployees,第 41 行 [批处理 Start Line 0] 'OFFSET' 附近的语法不正确。消息 153,级别 15,状态 2、Procedure GetEmployees, Line 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 

【问题讨论】:

  • OFFSETSQL Server 2008 中不可用,请改用row_number() 并使用您拥有的@PageSize 计算行号
  • Row Offset in SQL Server的可能重复

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


【解决方案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 中,我将逗号分隔的where 子句替换为CROSS JOIN

【讨论】:

  • 出现错误关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前面的语句必须以分号结束。 ',' 附近的语法不正确。
  • WITH 之前添加;,您可能复制了我的解决方案,而您现在没有。
【解决方案2】:

如果您使用 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

【讨论】:

    猜你喜欢
    • 2010-09-16
    • 2013-02-09
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2012-05-30
    相关资源
    最近更新 更多