1

ストアド プロシージャに 3 つのパラメータを渡しています@Time, @DeptID, @Value

  1. @Time1 = 過去 24 時間、2 = 過去 1 週間、3 = 過去 1 か月、4 = 過去 1 年を表します。
  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')

これは、1 つのパラメーターのみが渡される場合は問題ありませんが、2 つ以上のパラメーターでフィルター処理しようとすると問題が発生します...これまでのところ、最後に 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 ソリューションが必要な場合は、これが 1 つの方法です (ただし、最初に、このリンクを読みましたか?):

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

最後の 2 つの if ステートメントの基準が満たされ、 order 句を 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())' )
             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 に答える