お気づきのように、キーポイントはパラメーターを使用することです。IN
句は、厄介なことに、そのために悪名高い問題があります。ここで、値がすべて整数であることがわかっている場合 (たとえばint[]
、C# メソッドにパラメーターを取得している場合)、次のようなことでほぼ問題を解決できます。
cmd.CommandText = "SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN ("
+ string.Join(",", values) + "))"; // please don't!!!
それは恐ろしく、非常に悪い習慣を示唆しています (誰かが文字列のためにそれをコピーした場合、あなたは苦痛の世界にいます)、クエリプランのキャッシュを使用できません。次のようなことができます:
var sb = new StringBuilder("SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN (");
int idx = 0;
foreach(var val in values) {
if(idx != 0) sb.Append(',');
sb.Append("@p").Append(idx);
cmd.Parameters.AddWithValue("@p" + idx, val);
idx++
}
sb.Append("))");
cmd.CommandText = sb.ToString();
これは好ましいが厄介です。
または最も簡単: dapperのようなツールを使用して、ライブラリに心配させます。
var data = conn.Query<YourType>(
"SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN @values)",
new { values });
ここでdapperは使用法を見つけ、「正しいことを行います」。また、「0 値」のケースも処理します。