53

.Net のパラメーター化されたクエリは、例では常に次のようになります。

SqlCommand comm = new SqlCommand(@"
   SELECT * 
   FROM   Products 
   WHERE  Category_ID = @categoryid
", 
   conn);
comm.Parameters.Add("@categoryid", SqlDbType.Int);
comm.Parameters["@categoryid"].Value = CategoryID;

しかし、私は次のことをしようとしてレンガの壁にぶつかっています:

SqlCommand comm = new SqlCommand(@"
   SELECT * 
   FROM   Products 
   WHERE  Category_ID IN (@categoryids) 
      OR  name LIKE '%@name%'
", 
   conn);
comm.Parameters.Add("@categoryids", SqlDbType.Int);
comm.Parameters["@categoryids"].Value = CategoryIDs;
comm.Parameters.Add("@name", SqlDbType.Int);
comm.Parameters["@name"].Value = Name;

どこ

  • CategoryIDs は、数字 "123,456,789" (引用符なし) のカンマ区切りのリストです。
  • 名前は文字列です。単一引用符やその他の不適切な文字が含まれている可能性があります

これの正しい構文は何ですか?

4

4 に答える 4

61

整数配列にカテゴリ ID があり、Name が文字列であるとしましょう。秘訣は、コマンド テキストを作成して、すべてのカテゴリ ID を個別のパラメーターとして入力し、名前のあいまい一致を構築できるようにすることです。前者を実行するには、ループを使用して @p0 から @pN-1 までの一連のパラメーター名を作成します。ここで、N は配列内のカテゴリ ID の数です。次に、パラメータを作成し、関連付けられたカテゴリ ID を各名前付きパラメータの値としてコマンドに追加します。次に、クエリ自体で名前の連結を使用して、名前のあいまい検索を許可します。

string Name = "someone";
int[] categoryIDs = new int[] { 238, 1138, 1615, 1616, 1617,
                                1618, 1619, 1620, 1951, 1952,
                                1953, 1954, 1955, 1972, 2022 };

SqlCommand comm = conn.CreateCommand();

string[] parameters = new string[categoryIDs.Length];
for(int i=0;i<categoryIDs.Length;i++)
{
   parameters[i] = "@p"+i;
   comm.Parameters.AddWithValue(parameters[i], categoryIDs[i]);
}
comm.Parameters.AddWithValue("@name",$"%{Name}%");
comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN (";
comm.CommandText += string.Join(",", parameters) + ")";
comm.CommandText += " OR name LIKE @name";

これは、DBA を満足させる完全にパラメータ化されたクエリです。これらは整数であるため、名前をパラメーター化しながら、値を使用してコマンドテキストを直接構築するだけでは、セキュリティ上のリスクはそれほど大きくないと思います。カテゴリ ID が文字列配列にある場合は、配列をコンマで分割し、それぞれを整数に変換して、整数配列に格納します。

注:配列と言って例で使用していますが、反復はおそらく異なるものの、どのコレクションでも機能するはずです。

http://www.tek-tips.com/viewthread.cfm?qid=1502614&page=9からのオリジナルのアイデア

于 2008-11-19T21:26:52.063 に答える
17

SQL パラメータの値に「%」が必要です。

SqlCommand comm = new SqlCommand("SELECT * FROM Products WHERE Category_ID IN (@categoryid1, @categoryid2) OR name LIKE @name", conn);
comm.Parameters.Add("@categoryid1", SqlDbType.Int);
comm.Parameters["@categoryid1"].Value = CategoryID[0];
comm.Parameters.Add("@categoryid2", SqlDbType.Int);
comm.Parameters["@categoryid2"].Value = CategoryID[1];
comm.Parameters.Add("@name", SqlDbType.NVarChar);
comm.Parameters["@name"].Value = "%" + Name + "%";
于 2008-11-19T20:05:08.657 に答える
6

このアプローチは機能しません。限目。

IN 句はパラメーターのリスト自体を想定しているため、 1 つのパラメーターをそれにバインドすると、 1 つの値を渡す機会があります。

渡す予定の個々の IN 句プレースホルダーの正確な量を使用して、ステートメント文字列を動的に構築し、パラメーターを追加して、ループ内でそれらに値をバインドします。

于 2008-11-19T20:43:28.593 に答える
-2

これが正しい方法かどうかはわかりませんが、以前に行った方法です

list templist = 新しいリスト

comm.Parameters.Add("@categoryids", SqlDbType.varchar); comm.Parameters["@categoryids"].value = string.join(",",templist.toarray())

于 2008-11-19T20:37:07.140 に答える