我有这个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
可以是asc
或desc
,col_sort
是包含其中一个列名称的字符串。
这种情况下的过滤器无关紧要。
当col_sort
的值为product_id
或product_name
时,它工作正常,但当我使用produnit_name
调用它时,会抛出错误。
在这种情况下,如何按该列订购数据?
编辑:
错误是:
无效的列名'produnit_name'。
答案 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');