2011-12-17 112 views
1

我有一個存儲過程從表中返回前50行,像這樣:如何通過參數爲存儲過程指定列?

select top 50 
    Puzzle, 
    min(DateSolved) as CreationDate, 
    avg(SecondsToComplete) as AverageTime, 
    count(*) as TimesSolved 
    from CustomSolves 
    group by Puzzle 

但我想在存儲過程接受兩個參數,這樣我可以通過自定義列順序(創建日期,平均時間或時間),並且只選擇比特定日期更新的記錄。像這樣的僞SQL:

procedure SelectCustomPuzzles 
    @CutoffDate datetime, 
    @SortColumn column 
as 
    select top 50 
     Puzzle, 
     min(DateSolved) as CreationDate, 
     avg(SecondsToComplete) as AverageTime, 
     count(*) as TimesSolved 
    from CustomSolves 
    where CreationDate > @CutOffDate 
    group by Puzzle 
    order by @SortColumn 

我怎麼能去做這樣的事情呢?

回答

4
order by 
    CASE @SortColumn WHEN 'foo ASC' THEN foo ELSE NULL END, 
    CASE @SortColumn WHEN 'foo DESC' THEN foo ELSE NULL END DESC, 
    CASE @SortColumn WHEN 'bar ASC' THEN bar ELSE NULL END, 
    CASE @SortColumn WHEN 'bar DESC' THEN bar ELSE NULL END DESC, 

編輯,對默認排序添加這些

... 
CASE WHEN @SortColumn IS NULL THEN default ELSE NULL END DESC 

... 
defautcolumn 

注意事項之一:

  • ASC或DESC不能在CASE:必須是外
  • 具有多個WHEN..THEN column的單個CASE需要數據類型隱含CASTable。我喜歡獨立的CASE表達式,以避免隱式轉換爲一個樣例見https://dba.stackexchange.com/a/4166/630
+0

如何處理默認情況,以防排序列與任何情況不符? – 2011-12-17 18:28:08

+0

@Peter Olson:更新了答案 – gbn 2011-12-17 18:35:40

2

您可以使用case

order by case when @SortColumn = 'Puzzle' then Puzzle end, 
     case when @SortColumn = 'PuzzleDesc' then Puzzle end desc, 
     ... 

,如果你寫這樣的查詢數據庫無法使用索引。周圍的唯一方法是動態的SQL,如:

declare @sql nvarchar(max) 
set @sql = 'select * from tbl1 order by ' + @OrderByVar 
exec @sql 
+0

僅供參考,您的DESC是放錯了地方...... – gbn 2011-12-17 18:22:18

+0

編輯...你可以省略'其他null';) – Andomar 2011-12-17 18:24:48

2

除非你願意進入動態SQL領土(這將可能是類似的order by矯枉過正)考慮使用case-when

order by case(@SortColumn) 
    when 'ColumnName2' then ColumnName1 
    when 'ColumnName2' then ColumnName2 
    else ColumnName3 
end 

正如下面提到的gbn,這隻會工作,因爲你的三個排序列是相同的類型。如果不是這樣,你需要添加一個演員(可能到sql_variant),以便SQL服務器接受你的查詢。

+0

應注意這需要列數據類型兼容。 http://dba.stackexchange.com/a/4166/630 – gbn 2011-12-17 18:19:55

+0

@gbn感謝您的提示!我編輯了答案,提出瞭解決方法。 – dasblinkenlight 2011-12-17 18:25:01