【问题标题】:Is it possible to order by any column given a stored procedure parameter in SQL Server?是否可以按 SQL Server 中给定存储过程参数的任何列排序?
【发布时间】:2008-10-04 02:52:55
【问题描述】:

我正在研究根据给定一些输入指定的列对表格进行排序,根据我的发现,没有简单的方法可以做到这一点。我发现最好的是一个 switch 语句:

SELECT Column1, Column2, Column3, Column4
FROM Table
ORDER BY CASE WHEN @OrderBY = 'Column1' THEN Column1
              WHEN @OrderBY = 'Column2' THEN Column2
              WHEN @OrderBY = 'Column3' THEN Column3
              WHEN @OrderBY = 'Column4' THEN Column4

是否可以在没有 CASE 这样的声明的情况下执行此操作?如果表格变大并且需要对更多列进行排序,这可能会变得混乱。

我能够做到这一点的唯一方法就是连接一个大的 SQL 字符串,这在某种程度上破坏了存储过程的优势,并使 SQL 难以编写和维护。

【问题讨论】:

标签: sql-server database sql-server-2005


【解决方案1】:

你有两个选择:

  1. 正如您在上面实现的那样

  2. 或者生成动态sql并执行 使用sp_executesql

【讨论】:

  • 永远不要在存储过程内部或外部生成动态 SQL,因为优化后无法缓存语句,性能会下降
  • 这不是真的。我的同事发现,在某些情况下,生成的代码实际上比在存储过程中使用 @variables 更快。我们真的不知道为什么,但这是真的。 MSSQL2000, 80GB 数据库, 300+ 连接, 10~100 sql statements/sec, 复杂的存储过程
  • 使用 sp_executesql,SQL Server 存储语句的执行计划。如果您随后使用相同的查询但使用不同的参数调用 sp_executesql,则将重用执行计划。使用“exec”而不是保留任何计划,你会失去性能。
  • sp_executesql的主要问题是SQL注入漏洞
  • 当您可以在 ORDER BY 子句中使用 CASE 时,为什么要生成动态 SQL 以及所有相关风险?顺便说一句,我没有意识到你可以在 ORDER BY 中做决定 - 这是一个很好的接触。
【解决方案2】:

我通常将存储过程转换为返回表的函数(因此您可以选择 FROM 它...并在应用程序代码中将动态顺序按列添加到它:

Select
    *
From
   myTableFUnction()
Order by
   1, 2, 3, 6  <-- defined by application code in the SQL for the query

罗恩

【讨论】:

  • 另外,函数不能包含某些(非确定性)运算符。
【解决方案3】:

您已经编写了正确的语法:

SELECT Column1, Column2, Column3 
FROM SOME_TABLE
ORDER BY 1,2,3

试试看

【讨论】:

    【解决方案4】:

    SQL Server 和 Oracle 的 RANK 特性可以提高性能并使代码更简洁:

    SQL:

    DECLARE @column varchar(10)
    
    SET @column = 'D'
    
    SELECT *
    FROM Collection.Account AS A
    ORDER BY 
          CASE 
                WHEN @column = 'A' THEN (RANK() OVER(ORDER BY A.Code ASC))
                WHEN @column = 'D' THEN (RANK() OVER(ORDER BY A.Code DESC))
          END
    

    【讨论】:

      【解决方案5】:

      在这种情况下,除非您有一个非常大的数据集并且您需要利用数据库服务器的功能(瘦客户端、弱客户端机器等),否则最好在客户端内进行排序。

      【讨论】:

      • 为什么会这样呢?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      相关资源
      最近更新 更多