0

クエリ文字列パラメーターに基づいて MS SQL クエリを動的に作成しようとしています。

現在、有効なクエリ文字列パラメーターの値を要求する変数を使用しています。パラメーターが空でない場合、その変数は SQL ステートメントの一部を形成します。空の場合、変数は空白のままです。

例えば:

 var search = Request["search"].IsEmpty() ? "" : Request["search"];
 var price = Request["price"].IsEmpty() ? "" : Request["price"];

 string searchSQL = "WHERE item_name LIKE '%" + search + "%'";
 string priceSQL = " AND item_price < " + price;

 string sql = "SELECT * from Items " + searchSQL + priceSQL;

両方のクエリ パラメータが有効な場合、この SQL クエリは正常に実行されます。ただし、検索パラメーターが空で価格が空でない場合、SQL クエリは無効になります。

SELECT * from Items AND item_price < 100

私の計画では、最大 6 つの異なるクエリ文字列パラメーターを使用することになっているため、このコード スニペットは実際には使用できません。このタイプの方法のベスト プラクティスは何ですか? この方法で有効な動的 SQL ステートメントを作成することは可能ですか?

4

3 に答える 3

2

個人的には、Lasse V. Karlsenのアプローチを使用する傾向がありますが、動的 SQL を使用して、ユーザーがやりたいことに基づいてより効率的なクエリを生成するアプリケーションを 1 つ持っています (つまり、可能な場合は結合を減らします)。やめてください)。動的 SQL を本当に気に入っている場合は、三項演算子を使用してより適切なクエリを作成できます。

string search = Request("search").IsEmpty() ? "" : Request("search");
decimal price = Request("price").IsEmpty() ? "" : Request("price");
string param3 = Request("param3").IsEmpty() ? "" : Request("param3");
string param4 = Request("param4").IsEmpty() ? "" : Request("param4");
string param5 = Request("param5").IsEmpty() ? "" : Request("param5");
string param6 = Request("param6").IsEmpty() ? "" : Request("param6");

string whereClause = "";

whereClause += whereClause.length > 0 & search.length > 0 ? " AND item_name LIKE '%' + @search + '%'" : "WHERE item_name LIKE '%' + @search + '%'";
whereClause += whereClause.length > 0 & search.length > 0 ? " AND item_price < @price" : "WHERE item_price < @price";
whereClause += whereClause.length > 0 & search.length > 0 ? " AND param3 = @param3" : "WHERE param3 = @param3";
whereClause += whereClause.length > 0 & search.length > 0 ? " AND param4 = @param4" : "WHERE param4 = @param4";
whereClause += whereClause.length > 0 & search.length > 0 ? " AND param5 = @param5" : "WHERE param5 = @param5";
whereClause += whereClause.length > 0 & search.length > 0 ? " AND param6 = @param6" : "WHERE param6 = @param6";

string sql = "SELECT * from Items " + whereClause;

SqlConnection conn = new SqlConnection("your connection string");
SqlCommand cmd = new SqlCommand(sql, conn);

// fill in all parameters (even ones that may not exist)
cmd.Parameters.Add("search", SqlDbType.VarChar, 50).Value = search;
cmd.Parameters.Add("price", SqlDbType.Float).Value = price;
cmd.Parameters.Add("param3", SqlDbType.VarChar, 50).Value = param3;
cmd.Parameters.Add("param4", SqlDbType.VarChar, 50).Value = param4;
cmd.Parameters.Add("param5", SqlDbType.VarChar, 50).Value = param5;
cmd.Parameters.Add("param6", SqlDbType.VarChar, 50).Value = param6;
于 2013-06-24T15:55:03.600 に答える
0

Entity Frameworkor Linq2Sql(または同様の ORM フレームワーク)を使用するようにアプリケーションを変換する場合。コードでクエリを作成し、それをデータベースに送信できます。

以下は、Entity Framework を使用したコード例です。この例では、あなたの例に従って、DbSet<Item>からを使用しDbContextます。IQueryable<Item>などの多くの拡張メソッドからの戻り値の型でもある を継承しWhereます。一連の where ステートメントを連結して、必要なクエリを作成できるようになりました。

using (MyDbContext db = new MyDbContext())
{
    IQueryable<Item> items = db.Items;

    if (!string.IsNullOrEmpty(itemName))
        items = items.Where(s => s.Name.Contains(itemName));

    if (maxPrice > 0)
        items = items.Where(s => s.Price < maxPrice);

    // Get results
    List<Item> results = items.ToList();
}

ただし、これSELECT * from Items AND item_price < 100を作成するのは SQL ジェネレーター次第であるため、これから生成される SQL は より少し複雑になることに注意してください。

于 2013-12-02T00:09:44.263 に答える