如何在表值函数中使用动态'order by'

时间:2017-04-12 11:20:38

标签: sql sql-server user-defined-functions

我使用表值函数作为参数化视图。几乎一切都有效,除了'order by'部分。我将原来的功能改成了这个简短的功能。

功能:

ALTER FUNCTION [dbo].[fn_Get_NormalOrders]
(   
    @minimalLevel int,
    @recordStart int,
    @recordsEnd int,
    @orderBy varchar(30)
)
RETURNS TABLE 
AS
RETURN 
(
    select * 
        from
        (
            select 
                ROW_NUMBER() over (order by @orderBy) as row
                ,d.nameModel
                ,t.idToner
            from toner t
                inner join vwWebDevice d on d.idDevice = t.idDevice 
                    and d.statusDevice not like '%stale%'
                    and isnull(d.deleted,0) = 0
                inner join groups g on g.idGroup = d.idGroup
            where 
                t.currentLevel <= @minimalLevel
        ) as x
    where x.row between @recordStart and @recordsEnd
)

我通过创建此查询的varchar并执行此操作找到了解决方案,但是如何返回结果?当我现在使用它时,结果总是一样的。

2 个答案:

答案 0 :(得分:1)

您必须覆盖硬编码的所有列名称:

    var result = [];
    for (var name in array) {
      if (array.hasOwnProperty(name)) {
        result.push({name: name, array: array[name]});
      }
    }
    JSON.stringify(result) // use it to store in any variable.

答案 1 :(得分:0)

我很确定你不能轻易做到这一点。一种方法是case

. . .
order by (case when @OrderBy = 'col1' then col1 end),
         (case when @OrderBy = 'col2' then col2 end),
         . . .

(注意每种可能性都有一个单独的case。这可以防止用于排序的值出现类型冲突。)

不幸的是,参数不能替换列名或表达式。那将是最简单的解决方案。

另一种不起作用的可能性是动态SQL(你提到的“varchar”方法)。不幸的是,SQL Server中不允许使用动态SQL。

有一种非常复杂的方法,其中函数使用xp_cmdshell来绕过这些限制。为此目的,这可能不值得。

exec的限制是phrased by specifying that EXECUTE can only be used for extended stored procedures

EXECUTE statements calling extended stored procedures.