2

環境:

  • C#
  • ビジュアル スタジオ 2012
  • .NET フレームワーク 3.5

やあ

SQL Server で where 句をパラメーター化できますか?

私のシナリオでは、WHERE句の文字列が入力されると、アプリケーションはそれをクエリの他の部分に連結し、SQL Serverで実行してから結果を返します。

例えば、

  • ユーザー入力「[CookingTime] < 30 and [Cost] < 20」
  • アプリケーションはクエリ「select [RecipeID] from [Recipes] where [CookingTime] < 30 and [Cost] < 20」を作成し、SQL Server で実行します。
  • アプリケーションは結果をユーザーに返します。

セキュリティ上の理由から、WHERE句全体をパラメーターとして作成したいと思います。しかし、私は達成する方法がわかりません。

前もって感謝します。

4

4 に答える 4

0

元の質問は、ユーザーの入力から動的に作成し、適切な sql パラメータを使用してクエリを実行する方法を知りたかったのだと思います。

sql パラメータの使用については、通常、一般的なヘルパー メソッドを使用します。これは簡単な例です (テストされていません)。

public static class SqlHelpers
{
    public static IEnumerable<T> ExecuteAdhocQuery<T>(SqlConnection con, string sql, CommandType cmdType, Func<SqlDataReader, T> converter, params SqlParameter[] args)
    {
        try
        {
            using (SqlCommand cmd = new SqlCommand(sql, con) { CommandType = cmdType })
            {
                cmd.Parameters.AddRange(args);

                if (con.State != ConnectionState.Open) { con.Open(); }

                var ret = new List<T>();

                using (SqlDataReader rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        ret.Add(converter.Invoke(rdr));
                    }
                }

                return ret;
            }
        }
        catch (Exception e)
        {
            // log error?
            Console.WriteLine(e.Message);
            Console.WriteLine(e.StackTrace);
            throw e; // handle exception...
        }
    }

    public void Test()
    {
        using (SqlConnection con = new SqlConnection("connection string here"))
        {
            var data = ExecuteAdhocQuery(con,
                "SELECT ID, Name FROM tblMyTable WHERE ID = @Id and Status = @Status;",
                CommandType.Text, (x) => new { Id = x.GetInt32(0), Name = x.GetString(1) },
                new SqlParameter("@Id", SqlDbType.Int) { Value = 1 },
                new SqlParameter("@Status", SqlDbType.Bit) { Value = true });
            Console.WriteLine(data.Count());
        }
    }
}

もちろん、これは読み取りのみです。挿入/更新については、同様のメソッドも作成できます。

しかし、複雑な部分は、未知の数の条件とそれらの間の関係で動的にする方法です。したがって、委任されたメソッドまたはクラスを使用して作業を行うことをお勧めします。サンプル (未テスト):

    public static Dictionary<string, SqlParameter> GetParamsFromInputString(string inputString)
    {
        var output = new Dictionary<string, SqlParameter>();

        // use Regex to translate the input string (something like "[CookingTime] < 30 and [Cost] < 20" ) into a key value pair
        // and then build sql parameter and return out
        // The key will be the database field while the corresponding value is the sql param with value

        return output;
    }

    public void TestWithInput(string condition)
    {
        var parameters = GetParamsFromInputString(condition);

        // first build up the sql query:
        var sql = "SELECT Id, Name from tblMyTable WHERE " + parameters.Select(m => string.Format("{0}={1}", m.Key, m.Value.ParameterName)).Aggregate((m,n) => m + " AND " + n);
        using (SqlConnection con = new SqlConnection("connection string here"))
        {
            var data = ExecuteAdhocQuery(con,
                sql,
                CommandType.Text,
                (x) => new { Id = x.GetInt32(0), Name = x.GetString(1) },
                parameters.Select(m => m.Value).ToArray());
        }
    }

静的関数 GetParamsFromInputString の場合、これは単なるサンプルです。実際には、ニーズによっては非常に複雑になる可能性があります。

たとえば、演算子 (>、<、または <>、...) を含めることができます。

また、AND か OR かに関係なく、条件間の接続詞を含めることもできます。

非常に複雑な場合は、委任されたクラスを作成してその仕事を行います。

于 2013-08-30T04:48:50.603 に答える