ADO.NET IN句にSqlParameterCollection.AddWithValue メソッドを使う
概要
ADO.NETでIN句にパラメータを渡しても動かないという話を聞き、試してみたところ確かに想定した結果にならない!
検証
■データ
■ソース
using System; using System.Data.SqlClient; namespace AdonetParameter { class Program { static void Main(string[] args) { string connectionString = "Data Source=(localdb)\\v11.0;initial catalog=Simple;" + "Integrated Security=true"; string queryString = "SELECT * from dbo.myTable " + "WHERE Name IN (@param) "; string paramValue = "Test01,Test03,Test04"; using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(queryString, connection); command.Parameters.AddWithValue("@param", paramValue); try { connection.Open(); SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) { Console.WriteLine("\t{0}\t{1}\t{2}", reader[0], reader[1], reader[2]); } reader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } Console.ReadKey(); } } }
実行結果はデータがなにも取得できず。
指定した3つの値それぞれに一致する結果を取得する想定でしたが、そもそもSqlParameterはSQLインジェクション対策なので、一つの値として扱われているのでしょうね。
string queryString = "SELECT * from dbo.myTable " + "WHERE Name IN (@param) "; string paramValue = "Test01,Test03,Test04";
動的にパラメータを作るしかないかなと思っていたのですが、とあるブログ様*1でクエリを組み替えてLike句にすることで解決してました!
2017/9/12 コメントでご指摘いただき修正しました。
string queryString = "SELECT * from dbo.myTable " + "WHERE ',' + @param + ',' like '%,' + Name + ',%' ";
■実行結果
1 Test01 10 3 Test03 30 4 Test04 40
まとめ
柔軟な考え方って大切。
■補足:EFでのIN句実装
using (var context = new Model1()) { string[] paramValue = {"Test01","Test03","Test04" }; var data = context.myTables.Where(c => paramValue.Contains(c.Name)); foreach (var item in data) { Console.WriteLine("\t{0}\t{1}\t{2}", item.Id, item.Name, item.Value); } }
*1:勝手にリンクを張るのは気が引けるので控えます。ぐぐればすぐ見つかるはず!