无法动态排序 SQL
Not Able to Sorting in Dynamic SQL
我想根据传递给 SQL 服务器的 @SortDir
参数对数据进行排序。但是我得到一个错误:
Msg 156, Level 15, State 1, Line 62
Incorrect syntax near the keyword 'ASC'
这是我的动态SQL。我正在对列进行动态搜索,但无法对其进行排序
ALTER PROCEDURE Dsearchsor
@Name nvarchar(20),
@Description nvarchar(20),
@StartIndex int,
@PageSize int,
@SortDir nvarchar(20),
@SortField nvarchar(max)
AS
BEGIN
DECLARE @SQL nvarchar(max) = N''
DECLARE @Select nvarchar(max) = N'
;With data AS (Select P.Id,
P.Name,
P.Description,
P.Price,
P.Prorate,
B.Name as BillingPeriod,
P.CreatedDate,
CASE '+@SortField+'
WHEN P.Name THEN ROW_NUMBER() OVER (ORDER BY P.Name)
END rn '
DECLARE @From NVARCHAR(MAX) = N'From Products P '
DECLARE @WHERE NVARCHAR(MAX) = N''
IF @Name IS NOT NULL
BEGIN
SET @WHERE = @WHERE + 'Where P.Name LIKE ''' +'%'+@Name+'%' + ''''
END
IF @Description IS NOT NULL
BEGIN
IF LEN (@Where) > 0
BEGIN
SET @Where = @Where + ' AND '
END
SET @Where = @Where + 'Description LIKE ''' + +'%'+@Description+'%' + '''' +' )'
END
SET @From = @From + ' inner join BillingPeriods B on P.BillingPeriodId = B.Id '
SET @SQL = @Select + @From + @Where +'
Select *,(SELECT COUNT(1) FROM data) TotalCount From data
order by CASE WHEN '+ @SortDir +' = ASC' +' THEN rn ELSE -rn END ******This Line Gives Error******
OFFSET '+(CAST(@StartIndex as varchar(10)))+' ROWS FETCH NEXT '+(CAST(@PageSize as varchar(10)))+'
ROWS ONLY'
EXECUTE sp_executesql @SQL
END
帮我解决这个问题,我对 SQL 还很陌生。或者有更好的方法吗?如果是这样,请告诉我。
想想
order by CASE WHEN '+ @SortDir +' = ASC' +' THEN rn ELSE -rn END ******This Line Gives Error******
给予
order by CASE WHEN = ASC THEN rn ELSE -rn END
所以你应该转义ASC。可能还有@SortDir
order by CASE WHEN '''+ @SortDir +''' = ''ASC''' +' THEN rn ELSE -rn END
一些改进。
SET @SQL = @Select + @From + @Where + N'
...
order by rn ' + CASE WHEN UPPER(@SortDir) IN (N'ASC', N'DESC') THEN @SortDir
ELSE N'DESC' END
+ N' OFFSET @StartIndex ROWS FETCH NEXT @PageSize ROWS ONLY';
EXEC sys.sp_executesql @SQL,
N'@StartIndex int, @PageSize int',
@StartIndex, @PageSize;
- 您的
ORDER BY
不需要运行时 CASE
表达式,事实上,将逻辑放在外面并生成两个不同的查询文本几乎总是更好,这样您就可以获得不同的计划(一个方向可能更有效)。
- 您还应该确保传递给
@SortDir
的字符串是您期望的字符串。
OFFSET
/ FETCH NEXT
接受参数,所以你应该显式传递这些参数,而不是乱七八糟的字符串连接。
- 您应该考虑将
@SortField
更改为 nvarchar(128)
(没有理由将其更改为 max
)并检查它是否包含有效的列名(请参阅两个“保护自己”文章)。
一些可能有用的文章:
我想根据传递给 SQL 服务器的 @SortDir
参数对数据进行排序。但是我得到一个错误:
Msg 156, Level 15, State 1, Line 62
Incorrect syntax near the keyword 'ASC'
这是我的动态SQL。我正在对列进行动态搜索,但无法对其进行排序
ALTER PROCEDURE Dsearchsor
@Name nvarchar(20),
@Description nvarchar(20),
@StartIndex int,
@PageSize int,
@SortDir nvarchar(20),
@SortField nvarchar(max)
AS
BEGIN
DECLARE @SQL nvarchar(max) = N''
DECLARE @Select nvarchar(max) = N'
;With data AS (Select P.Id,
P.Name,
P.Description,
P.Price,
P.Prorate,
B.Name as BillingPeriod,
P.CreatedDate,
CASE '+@SortField+'
WHEN P.Name THEN ROW_NUMBER() OVER (ORDER BY P.Name)
END rn '
DECLARE @From NVARCHAR(MAX) = N'From Products P '
DECLARE @WHERE NVARCHAR(MAX) = N''
IF @Name IS NOT NULL
BEGIN
SET @WHERE = @WHERE + 'Where P.Name LIKE ''' +'%'+@Name+'%' + ''''
END
IF @Description IS NOT NULL
BEGIN
IF LEN (@Where) > 0
BEGIN
SET @Where = @Where + ' AND '
END
SET @Where = @Where + 'Description LIKE ''' + +'%'+@Description+'%' + '''' +' )'
END
SET @From = @From + ' inner join BillingPeriods B on P.BillingPeriodId = B.Id '
SET @SQL = @Select + @From + @Where +'
Select *,(SELECT COUNT(1) FROM data) TotalCount From data
order by CASE WHEN '+ @SortDir +' = ASC' +' THEN rn ELSE -rn END ******This Line Gives Error******
OFFSET '+(CAST(@StartIndex as varchar(10)))+' ROWS FETCH NEXT '+(CAST(@PageSize as varchar(10)))+'
ROWS ONLY'
EXECUTE sp_executesql @SQL
END
帮我解决这个问题,我对 SQL 还很陌生。或者有更好的方法吗?如果是这样,请告诉我。
想想
order by CASE WHEN '+ @SortDir +' = ASC' +' THEN rn ELSE -rn END ******This Line Gives Error******
给予
order by CASE WHEN = ASC THEN rn ELSE -rn END
所以你应该转义ASC。可能还有@SortDir
order by CASE WHEN '''+ @SortDir +''' = ''ASC''' +' THEN rn ELSE -rn END
一些改进。
SET @SQL = @Select + @From + @Where + N'
...
order by rn ' + CASE WHEN UPPER(@SortDir) IN (N'ASC', N'DESC') THEN @SortDir
ELSE N'DESC' END
+ N' OFFSET @StartIndex ROWS FETCH NEXT @PageSize ROWS ONLY';
EXEC sys.sp_executesql @SQL,
N'@StartIndex int, @PageSize int',
@StartIndex, @PageSize;
- 您的
ORDER BY
不需要运行时CASE
表达式,事实上,将逻辑放在外面并生成两个不同的查询文本几乎总是更好,这样您就可以获得不同的计划(一个方向可能更有效)。 - 您还应该确保传递给
@SortDir
的字符串是您期望的字符串。 OFFSET
/FETCH NEXT
接受参数,所以你应该显式传递这些参数,而不是乱七八糟的字符串连接。- 您应该考虑将
@SortField
更改为nvarchar(128)
(没有理由将其更改为max
)并检查它是否包含有效的列名(请参阅两个“保护自己”文章)。
一些可能有用的文章: