2009-04-27 57 views
2

我正在处理这个例子。如何运行查询以使用参数对列和asc/desc进行排序?

http://www.drury.net.nz/2005/04/15/specifying-a-sort-parameter-for-a-tsql-stored-procedure/

CREATE PROCEDURE getEmployees (@ColumnName varchar(100)) 
AS 
    SELECT 
    EmployeeID, 
    FirstName, 
    LastName, 
    SSN, 
    Salary 
    FROM 
    Employees 
    ORDER BY 
    CASE 
     WHEN @ColumnName=’LastName’ THEN LastName 
     WHEN @ColumnName=’Salary’ THEN CONVERT(varchar(50), Salary) 
     WHEN @ColumnName=’SSN’ THEN SSN 
    END 

case语句的作品,但如果我有以下参数:@SortColumn,@SortDirection。

@SortColumn可以是任何类型的任何列,它似乎使用case语句,您必须将值转换为相同的类型。我想我可以让它们都成为VARCHAR,并且只要确保像DateTime这样的值按正确的顺序放置就可以按我的意愿排序。

但是如果我将@SortDirection参数设置为ASC或DESC作为VARCHAR值怎么办?如何调整查询以改变排序方向?

回答

4

如果你不想使用动态SQL,那么你可以这样做,通过使case语句导致where子句的非过滤部分;它不会很快。您还需要小心您的病例部分中的类型是否匹配。

SELECT 
    * 
FROM 
    dbo.Contacts 
ORDER BY 
    CASE @Sort 
     WHEN 1 THEN Surname 
     WHEN 2 THEN Forename 
     WHEN 3 THEN Telephone_Number 
     ELSE  '' 
    END ASC 
    , 
    CASE @Sort 
     WHEN 4 THEN Personnel_Ref 
     WHEN 5 THEN timesheet_number 
     WHEN 6 THEN Telephone_Number 
     ELSE  '' 
    END DESC 
0

您可以使用动态查询。

举一个例子,看看here

+0

我已经考虑动态查询,但我正在尽我所能避免它们。我曾经看到我可以使用参数进行排序,但我不记得如何完成这项工作。 – Brennan 2009-04-27 23:45:38

+0

你应该尽可能避免动态查询或游标。 – Sung 2009-04-28 02:47:16

0

我觉得你的诗情会是这样的:

如果你有

@SortColumn varchar(50), @SortDirection varchar(50) 

,那么你可以这样做:

DECLARE @sql nvarchar(4000)  
SET @sql = N'SELECT EmployeeID, FirstName, LastName, SSN, Salary ' + 
      'FROM Employees ' + 
      'ORDER BY ' + @SortColumn + ' ' + @SortDirection  
EXEC sp_executesql @sql 

当然,你可以在存储过程中放或任何你想要的。

+0

你知道我如何避免使用sp_executesql吗?我听说如果你使用它,那么它不能缓存查询计划。 – Brennan 2009-04-28 00:16:03

0

Employee表的select语句的结果放入表变量或临时表中。

然后使用if..else语句返回结果升序/降序。

使用if..else没有任何问题。

1

(我没有足够的声誉显然发表评论,所以我回答在这里)

在回答:

你知道我怎么能避免使用sp_executesql的?我听说如果你使用 那么它不能缓存查询计划。 - Brennan 4月28日0:16

实际上,在大多数情况下,sp_executesql允许将查询计划缓存为与存储过程相同。

的诀窍是使用参数化动态SQL,像这样:

exec sp_executesql N'select from MyTable where myId = @id', N'@id int', @id; 

这样,你正在运行相同的查询,只需在@id替代,就像使用存储过程。通过动态sql,查询计划将基于查询的字符串值(sp_executesql的第一个参数)进行缓存。

我想问的唯一问题是为什么你必须在数据库中对此进行排序?我觉得你应该稍后对它进行排序......

但是,由于排序表达式和方向不能被参数化(它们必须连接到查询字符串中),因此您将获得单独的查询计划缓存为每一种排序表达和方向。这可能不是什么大不了的事情。

编辑: 下面是解释如何dynamic SQL query plans are cached

相关问题