使用从sql函数获取的值时的ORDER BY

时间:2013-03-26 13:00:58

标签: sql-server tsql stored-procedures

我有这个SQL用于创建过程:

create procedure [dbo].[spGetProduct](@col_sort varchar(100), @dir_sort varchar(4), @filters nvarchar(max)) as
begin
declare @temp table (
        row_num int,
        product_id int,
        product_name nvarchar(255),
        produnit_name nvarchar(50)
    )

insert into @temp
    EXEC('select * from (select (ROW_NUMBER() OVER (ORDER BY '+@col_sort+' '+@dir_sort+')) row_num, product_id, product_name, dbo.fnGetUnitName(ing_produnit) produnit_name
     from dbo.Products
     where '+@filters+') as tmp)

select * from @temp
end

的信息:

dir_sort可以是ascdesccol_sort是包含其中一个列名称的字符串。

这种情况下的过滤器无关紧要。

col_sort的值为product_idproduct_name时,它工作正常,但当我使用produnit_name调用它时,会抛出错误。

在这种情况下,如何按该列订购数据?

编辑:

错误是:

  

无效的列名'produnit_name'。

2 个答案:

答案 0 :(得分:1)

这是因为produnit_name是派生列。虽然您可以在ORDER BY子句中使用派生列,但不能将其与ROW_NUMBER OVER一起使用。

答案 1 :(得分:1)

您无法在同一作用域的OVER()子句中引用别名,因为在评估了OVER()子句之后定义了别名。这与您无法GROUP BY alias或说WHERE alias = 1的原因相同 - 在这些情况下,别名尚未定义。

如果您不能使用连接而不是函数来派生单位名称,那么您将不得不再次嵌套,例如

insert into @temp
EXEC('select * from (select (ROW_NUMBER() OVER 
  (ORDER BY '+@col_sort+' '+@dir_sort+')) row_num, * FROM 
    (SELECT product_id, product_name, 
      dbo.fnGetUnitName(ing_produnit) produnit_name
      from dbo.Products
      where '+@filters+') AS x) as tmp');