2011-12-17 107 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