3

SQL Server で SEQUENCE オブジェクトを試しており、シーケンス名を指定して C# で次の値を取得しています。範囲にはストアド プロシージャがあり、シーケンス名を渡すことができるため、範囲は単純です。

    public static T Reserve<T>(string name, int count, SqlConnection sqlConn)
    {
        using (var sqlCmd = new SqlCommand("sp_sequence_get_range", sqlConn))
        {
            sqlCmd.CommandType = CommandType.StoredProcedure;
            var firstValueParam = new SqlParameter("@range_first_value", SqlDbType.Variant) { Direction = ParameterDirection.Output };

            sqlCmd.Parameters.AddWithValue("@sequence_name", name);
            sqlCmd.Parameters.AddWithValue("@range_size", count);
            sqlCmd.Parameters.Add(firstValueParam);

            sqlCmd.ExecuteNonQuery();

            return (T)firstValueParam.Value;
        }
    }

しかし、単一の値はどうでしょうか? 上記を「1」のカウントで呼び出すか、SQLを動的に構築できるように思えます。すなわち

var sqlCmdStr = string.Format("SELECT NEXT VALUE FOR {0}", name);

これは一般的に悪い習慣であることがわかっています(つまり、SQLインジェクション)。

誰が何を提案しますか?

4

4 に答える 4

5

これは一般的に悪い習慣であることがわかっています(つまり、SQLインジェクション)。

すべての動的 SQL が悪いわけではありません。

SQL インジェクションを受け入れるかどうかは、(SQL テキストに挿入される) 値がどこから来るかによって異なります。コードの厳密な制御下にある場所 (たとえば、switch一連の文字列定数から選択するステートメント) からのものである場合、SQL インジェクションは問題になりません。

または、単純にシーケンスごとに個別のクエリを作成することもできます (シーケンスがそれほど多くない場合)。

于 2013-01-08T17:40:05.387 に答える
2

私の提案は、@Gserg の回答と現在のソリューションの両方を組み合わせたものです。VARCHARパラメータ @Nameを取るストアド プロシージャを記述します。QUOTENAME@GSerg の提案に従って、ストアド プロシージャで SQL 文字列を作成します。EXECまたはを使用sp_executesqlしてスクリプトを実行します。

このようなもの(フリーハンド):

CREATE PROCEDURE [GetNext]
    @Name VARCHAR(50)
AS
BEGIN
    DECLARE @sql VARCHAR(200);
    SET @Name = QUOTENAME(@Name, '[');
    SET @sql = 'SELECT NEXT VALUE FOR ' + @Name;

    EXEC (@sql);
END
于 2013-01-08T17:56:53.767 に答える
0

同様のことをする必要があるときは、次のようにします。

string sanitized_name;
using (var sqlCmd = new SqlCommand("select quotename(@unsafe_name, '[');", sqlConn))
{
    sqlCmd.Parameters.AddWithValue("@unsafe_name", name);

    sanitized_name = (string)sqlCmd.ExecuteScalar();
}

using (var sqlCmd = new SqlCommand(string.Format("select next value for {0};", sanitized_name), sqlConn))
{
    ...
}

または、同じことを行うサーバー側の手順を作成します。

于 2013-01-08T17:38:46.310 に答える