如何根据传递到存储过程的参数更改 ORDER BY 子句

Tre*_*NGC 1 sql sql-server stored-procedures dynamic-sql sql-order-by

我将 3 个参数传递到我的存储过程中:@Time, @DeptID, @Value

  1. @Time代表:1=过去24小时,2=过去一周,3=过去一个月,4=过去一年
  2. @DeptID是各个部门的ID
  3. @Value1=按低位排序,2=按高位排序

这是我当前的代码:

DECLARE @SQL VARCHAR(MAX)
SET @SQL = ('SELECT S.ID, S.[Description], D.Department, S.Value, S.[Date] FROM Suggestions S INNER JOIN Department D ON D.ID = S.DeptID WHERE Approved =1')

IF (@DeptID = 0 AND @Value = 0 AND @Time = 0)
    BEGIN
        SET @SQL = (@SQL +' ORDER BY [Date] DESC')
    END

IF (@Time > 0)
   BEGIN
    SET @SQL = (CASE WHEN @Time = 1 THEN (@SQL + ' AND [Date] >= DATEADD(DAY, -1, GETDATE()) ORDER BY S.[Date] DESC')
             WHEN @Time = 2 THEN (@SQL + ' AND [Date] >= DATEADD(DAY, -7, GETDATE()) ORDER BY S.[Date] DESC' )
             WHEN @Time = 3 THEN (@SQL + ' AND [Date] >= DATEADD(DAY, -30, GETDATE()) ORDER BY S.[Date] DESC')
             WHEN @Time = 4 THEN (@SQL + ' AND [Date] >= DATEADD(DAY, -365, GETDATE()) ORDER BY S.[Date] DESC') END)
   END

IF (@DeptID > 0)
   BEGIN
    SET @SQL = @SQL + ' AND S.DeptID = @DeptID ORDER BY S.[Date] DESC')
   END

IF (@Value > 0)
   BEGIN
    SET @SQL = (CASE WHEN @Value = 1 THEN (@SQL + ' ORDER BY S.Value DESC')
             WHEN @Value = 2 THEN (@SQL + ' ORDER BY S.Value ASC')
Run Code Online (Sandbox Code Playgroud)

当仅传入一个参数时,这很好,但是当尝试按两个或多个参数进行过滤时,我会遇到问题...到目前为止,我一直收到错误,因为我在末尾添加了 2 个“Order By”子句我的声明:

ORDER BY S.[Date] DESC ORDER BY S.Value DESC
Run Code Online (Sandbox Code Playgroud)

谁能指出我正确的方向吗?任何帮助都会非常感激

Lam*_*mak 5

我重写了你的代码,不使用动态 SQL:

SELECT  S.ID, 
        S.[Description], 
        D.Department, 
        S.Value, 
        S.[Date] 
FROM Suggestions S 
INNER JOIN Department D 
    ON D.ID = S.DeptID 
WHERE Approved =1
AND (@Time = 0 
     OR (@Time = 1 AND [Date] >= DATEADD(DAY, -1, GETDATE()))
     OR (@Time = 2 AND [Date] >= DATEADD(DAY, -30, GETDATE()))
     OR (@Time = 3 AND [Date] >= DATEADD(DAY, -365, GETDATE()))
    )
AND (@DeptID = 0
     OR (@DeptID > 0 AND S.DeptID = @DeptID)
    )
ORDER BY [Date] DESC,
         CASE WHEN @Value = 1 THEN S.Value
         ELSE 1 END DESC,
         CASE WHEN @Value = 2 THEN S.Value
         ELSE 1 END ASC
Run Code Online (Sandbox Code Playgroud)

使用动态 SQL 版本进行更新

好的,如果您想要动态 SQL 解决方案,那么这是一种方法(但首先,您阅读此链接了吗?):

DECLARE @SQL VARCHAR(MAX), @WHERE VARCHAR(MAX), @ORDER VARCHAR(MAX)
SET @SQL = ('SELECT S.ID, S.[Description], D.Department, S.Value, S.[Date] FROM Suggestions S INNER JOIN Department D ON D.ID = S.DeptID WHERE Approved =1')

SET @WHERE = ' AND ' + 
             CASE WHEN @Time = 0 THEN '1 = 1'
             WHEN @Time = 1 THEN '[Date] >= DATEADD(DAY, -1, GETDATE())'
             WHEN @Time = 2 THEN '[Date] >= DATEADD(DAY, -7, GETDATE())'
             WHEN @Time = 3 THEN '[Date] >= DATEADD(DAY, -30, GETDATE())'
             WHEN @Time = 4 THEN '[Date] >= DATEADD(DAY, -365, GETDATE())' END

SET @WHERE = @WHERE + 
             CASE WHEN @DeptID > 0 THEN ' AND S.DeptID = @DeptID'
             ELSE '' END

SET @ORDER = ' ORDER BY S.[Date] DESC' + 
             CASE WHEN @Value = 0 THEN ''
             WHEN @Value = 1 THEN ', S.Value DESC'           
             WHEN @Value = 2 THEN ', S.Value ASC' END

SET @SQL = @SQL + @WHERE + @ORDER

PRINT @SQL
Run Code Online (Sandbox Code Playgroud)