无法在动态sql中排序

5sxhfpxr  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(611)

我想根据 @SortDir 我正在传递给sql server的参数。但我有个错误:
消息156,级别15,状态1,行62
关键字“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还很陌生。还是有更好的办法?如果是,请告诉我。

enxuqcxy

enxuqcxy1#

认为

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
kupeojn6

kupeojn62#

一些改进。

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 获取参数,因此应该显式传递这些参数,而不是混乱的字符串连接。
你应该考虑改变 @SortFieldnvarchar(128) (这是没有理由的 max )还要检查它是否包含有效的列名(请参阅下面的两篇“保护自己”文章)。
一些可能有用的文章:
用偏移/取数分页:一种更好的方法

backtobasics:一个更新的厨房Flume示例

防止sql server中的sql注入-第1部分
防止sql server中的sql注入-第2部分

相关问题