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.GridSortExpressionあり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 に答える