如何运行查询以按列排序和使用参数asc / desc?

时间:2009-04-27 23:41:21

标签: sql sql-server tsql

我正在处理这个例子。

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值,该怎么办?如何调整查询以更改排序方向?

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

回复:

  

你知道如何避免使用sp_executesql吗?我听说如果你使用   然后它无法缓存查询计划。 - 布伦南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

的链接

答案 2 :(得分:0)

您可以使用动态查询。

例如,看看here

答案 3 :(得分: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

当然,您可以放入存储过程或任何您想要的内容。

答案 4 :(得分:0)

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

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

使用if..else没有错。