【问题标题】:How can I run a query to sort by a column and asc/desc using parameters?如何运行查询以使用参数按列和 asc/desc 排序?
【发布时间】:2009-04-27 23:41:20
【问题描述】:

我正在处理这个例子。

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 值呢?如何调整查询以更改排序方向?

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    如果您不想使用动态 SQL,那么您可以通过使用导致 where 子句的未过滤部分的 case 语句来执行此操作;不过它不会很快。您还需要注意案例部分中的类型是否匹配。

    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
    

    【讨论】:

      【解决方案2】:

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

      回复:

      你知道如何避免使用 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的链接。

      【讨论】:

        【解决方案3】:

        您可以使用动态查询。

        例如,看看here。

        【讨论】:

        • 我已经考虑过动态查询,但我正在尽力避免它们。我曾经看到我可以使用参数进行排序,但我不记得如何做到这一点。
        • 您当然应该尽量避免使用动态查询或游标。
        【解决方案4】:

        我想你的场景应该是这样的:

        如果你有

        @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
        

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

        【讨论】:

        • 您知道如何避免使用 sp_executesql 吗?我听说如果你使用它,它就不能缓存查询计划。
        • 嗯,是的。如果您使用 sp_executesql,将不会成为您的查询计划,但由于您的查询很简单,您真的需要计划吗?
        • 问题是你不能授予权限,他们不能与 sp_executesql 一起工作
        【解决方案5】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2014-07-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-14
          • 2012-05-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多