" Order By"使用列名称的参数

时间:2012-12-12 16:53:41

标签: sql sql-server visual-studio parameters sql-order-by

我们希望在使用Visual Studio DataSet Designer创建的查询或存储过程的“Order By”子句中使用参数。

示例:

  FROM TableName
 WHERE (Forename LIKE '%' + @SearchValue + '%') OR
       (Surname LIKE '%' + @SearchValue + '%') OR
       (@SearchValue = 'ALL')
ORDER BY @OrderByColumn

显示以下错误:

Variables are only allowed when ordering by an expression referencing 
a column name.

2 个答案:

答案 0 :(得分:40)

你应该可以这样做:

SELECT *
FROM
    TableName
WHERE
    (Forename LIKE '%' + @SearchValue + '%') OR
    (Surname LIKE '%' + @SearchValue + '%') OR
    (@SearchValue = 'ALL')
ORDER BY 
    CASE @OrderByColumn
    WHEN 1 THEN Forename
    WHEN 2 THEN Surname
    END;
  • 将1分配给@OrderByColumn以对Forename进行排序。
  • 分配2以对Surname进行排序。
  • 等等......您可以将此方案扩展为任意数量的列。

虽然要注意性能。这些类型的构造可能会干扰查询优化器找到最佳执行计划的能力。例如,即使索引覆盖Forename,查询仍可能需要完整排序,而不是仅按顺序遍历索引。

如果是这种情况,并且您无法忍受性能影响,则可能需要为每个可能的排序顺序提供单独的查询版本,这会使客户端的内容变得复杂。

答案 1 :(得分:1)

我知道我要晚些使用这种线程了,但是我只想发布此消息,以防其他人遇到类似的问题。

当您尝试直接对参数执行ORDER BY时,似乎会出现此问题,因为SQL Server希望您提供一个数字(第一个字段为1,第二个字段为2,依此类推。 )或以标识符(MyField或“ MyField”)或字符串(“ MyField”)形式显示的列名。

例如:

DECLARE @ORDERBY AS NVARCHAR(20)
;

SELECT @ORDERBY = :Param1 --(Supposing that the user enters 'MyField')
;

SELECT TOP 1 *
FROM MyTable
ORDER BY @ORDERBY DESC
;

您收到以下错误:

  

由ORDER BY数字1标识的SELECT项包含一个   变量作为表示列位置的表达式的一部分。   仅在通过表达式引用进行排序时才允许使用变量   列名。 (SQLSTATE = 42000)(1008)(Severity = 16)

如果您以上述任何一种方式(使用标识符或字符串)手动写出查询,则不会出现错误。

SELECT TOP 1 *
FROM MyTable
ORDER BY MyField DESC
;

SELECT TOP 1 *
FROM MyTable
ORDER BY "MyField" DESC
;

SELECT TOP 1 *
FROM MyTable
ORDER BY 'MyField' DESC
;

因此,如果您对同一参数执行CAST(),则其值将转换为字符串,并且查询将成功执行:

DECLARE @ORDERBY AS NVARCHAR(20)
;

SELECT @ORDERBY = :Param1 --(Supposing that the user enters the text 'MyField')
;

SELECT TOP 1 *
FROM MyTable
ORDER BY CAST(@ORDERBY AS NVARCHAR(20)) DESC
;

在这种情况下(同样,假设用户将字符串“ MyField”写为:Param1的值),正在执行的实际查询是:

SELECT TOP 1 *
FROM MyTable
ORDER BY 'MyField' DESC
;

此查询成功执行,没有错误,对性能没有明显影响,而无需将所有可能的用户输入枚举到CASE语句中,该语句可能扩展到数百个值。

从2005年到2016年,我在Microsoft SQL Server中多次使用此解决方案,没有任何问题。

希望这对某人还是有帮助的。