1

我创建了下面列出的查询。当我运行它时它工作。

string sortDir = (this.GridSortDirection == SortDirection.Descending ? " DESC" : " ASC");
int startIndex = 1;
int endIndex = this.gvData.PageSize;

SELECT RowNum, [ID], [Name], [Description], [DisplayIndex], [Status] 
FROM
(
    SELECT  [ID], [Name], [Description], [DisplayIndex], CASE WHEN Status = 1 THEN 'Active' ELSE 'Disabled' END AS [Status] ,
    ROW_NUMBER() OVER(ORDER BY [" + this.GridSortExpression + "]" + " " + sortDir + @")as 'RowNum'
    FROM  [MyDatabase].[dbo].[t_MyTable] s

) as Info
WHERE RowNum BETWEEN " + startIndex.ToString() + " AND " + endIndex.ToString()

我尝试将其重组为参数化查询格式,如下所示,但运行时出现错误。该错误表明 sortDir 附近存在语法错误。

string sql = @"SELECT RowNum, [ID], [Name], [Description], [DisplayIndex], [Status] 
FROM
(
    SELECT  [ID], [Name], [Description], [DisplayIndex], CASE WHEN Status = 1 THEN 'Active' ELSE 'Disabled' END AS [Status] ,
    ROW_NUMBER() OVER(ORDER BY @SortExpression @SortDir)as 'RowNum'
    FROM  [MyDatabase].[dbo].[t_MyTable] s

) as Info
WHERE RowNum BETWEEN @startIndex AND @endIndex";

cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@SortExpression", this.GridSortExpression);   
cmd.Parameters.AddWithValue("@SortDir", sortDir);                 
cmd.Parameters.AddWithValue("@startIndex", startIndex);
cmd.Parameters.AddWithValue("@endIndex", endIndex);
da = new SqlDataAdapter(cmd);
da.Fill(dt);

我也尝试了以下无济于事...相同的错误消息

cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@SortExpression", this.GridSortExpression + " " + sortDir);                    
cmd.Parameters.AddWithValue("@startIndex", startIndex);
cmd.Parameters.AddWithValue("@endIndex", endIndex);
da = new SqlDataAdapter(cmd);
da.Fill(dt);

任何人都可以参考我的错误吗?

提前谢谢了

4

2 回答 2

4

@SortExpression并且@SortDir不能参数化。它们是 T-SQL 语法的一部分,而不是值。您必须将它们留在命令文本字符串中。相比之下@startIndex,and@endIndex是值,因此可以作为参数正常工作。

如果您担心 SQL 注入,那么恐怕您将不得不编写自己的代码来验证this.GridSortExpressionand的内容sortDir。例如:

  • 您可以检查是否sortDir等于"asc""desc"拒绝其他任何内容。
  • 您可以从 中解析出列名列表this.GridSortExpression,然后将每个列放在方括号中,然后再将列表重新组合在一起。
于 2012-07-25T19:20:34.600 回答
1

可以使用 CASE 语句进行条件排序。

例如:

ORDER BY
     CASE
         WHEN @SortCol = 'a' THEN colA
         WHEN @SortCol = 'b' THEN colB
     END DESC

您可以进一步扩展它以按方向排序。

ORDER BY
    CASE WHEN @SortCol = 'a' AND @SortDir = 'ASC' THEN ColA END ASC
    ,CASE WHEN @SortCol = 'a' AND @SortDir = 'DESC' THEN ColA END DESC
    ,CASE WHEN @SortCol = 'b' AND @SortDir = 'ASC' THEN ColB END ASC
    ,CASE WHEN @SortCol = 'b' AND @SortDir = 'DESC' THEN ColB END DESC

上次我使用它时,我有一个@KeyDataColumn,我想对其进行排序、分组并在结果集中返回。与其将这个逻辑重复 3 次,我发现将逻辑封装在子查询中更方便、可读和可扩展。

SELECT
    keyData.KeyDataColumn
    ,COUNT(base.*) AS KeyDataCount
FROM baseTable base
    CROSS APPLY (
        SELECT
            CASE
                WHEN @KeyDataColumn = 'NextEvolution' THEN base.NextEvolution
                WHEN @KeyDataColumn = 'TimesCaptured' THEN base.TimesCaptured
                WHEN @KeyDataColumn = 'BattlesWon' THEN base.BattlesWon
            END AS KeyDataColumn
    ) keyData
GROUP BY keyData.KeyDataColumn
ORDER BY
    CASE WHEN @SortDir = 'ASC' THEN keyData.KeyDataColumn END ASC
    ,CASE WHEN @SortDir = 'DESC' THEN keyData.KeyDataColumn END DESC
于 2012-08-09T08:31:34.470 回答