1

我将 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')

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

ORDER BY S.[Date] DESC ORDER BY S.Value DESC

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

4

4 回答 4

4

我重写了您的代码以不使用动态 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

使用动态 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
于 2013-09-12T14:20:27.460 回答
1

不确定我是否同意您的所有动态 SQL,但为什么不检查 order by 子句是否已经在 SQL 字符串中,如果它只是添加附加参数,否则添加整个子句。您可以使用 CharIndex 执行此操作。

我还建议仅在执行 @SQL 之前的最后添加 DESC

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

SET @SQL = @SQL + ' DESC'
于 2013-09-12T14:46:19.093 回答
0
DECLARE @STARTDATE datetime = CASE @Time 
                    WHEN 1 THEN DATEADD(dd, -1, GETDATE())
                    WHEN 2 THEN DATEADD(ww, -1, GETDATE())
                    WHEN 3 THEN DATEADD(mm, -1, GETDATE())
                    WHEN 4 THEN DATEADD(yy, -1, GETDATE())
                END

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
        (S.DeptID = @DeptId OR @DeptID = 0) AND
        [DATEADD] >= @STARTDATE
ORDER BY case @Value when 0 then [Date] else 0 end,
        case @Value when 1 then S.Value else S.Value * -1 end
于 2013-09-12T14:24:47.217 回答
0

它看起来像您最后两个 if 语句的标准,并且您要添加两次 order 子句。

尝试这个:

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())' )
             WHEN @Time = 3 THEN (@SQL + ' AND [Date] >= DATEADD(DAY, -30, GETDATE())')
             WHEN @Time = 4 THEN (@SQL + ' AND [Date] >= DATEADD(DAY, -365,GETDATE())') END)
   END

IF (@DeptID > 0)
   BEGIN
    SET @SQL = @SQL + ' AND S.DeptID = @DeptID')
   END

IF (@Value > 0)
   BEGIN
    SET @SQL = (CASE WHEN @Value = 1 THEN (@SQL + '  ORDER BY S.[Date] DESC, S.Value DESC')
             WHEN @Value = 2 THEN (@SQL + ' ORDER BY S.[Date] ASC, S.Value ASC')
于 2013-09-12T14:37:52.730 回答