Anda dapat membuat parameter setiap nilai, jadi seperti:
string[] tags = new string[] { "ruby", "rails", "scruffy", "rubyonrails" };
string cmdText = "SELECT * FROM Tags WHERE Name IN ({0})";
string[] paramNames = tags.Select(
(s, i) => "@tag" + i.ToString()
).ToArray();
string inClause = string.Join(", ", paramNames);
using (SqlCommand cmd = new SqlCommand(string.Format(cmdText, inClause))) {
for(int i = 0; i < paramNames.Length; i++) {
cmd.Parameters.AddWithValue(paramNames[i], tags[i]);
}
}
Yang akan memberi Anda:
cmd.CommandText = "SELECT * FROM Tags WHERE Name IN (@tag0, @tag1, @tag2, @tag3)"
cmd.Parameters["@tag0"] = "ruby"
cmd.Parameters["@tag1"] = "rails"
cmd.Parameters["@tag2"] = "scruffy"
cmd.Parameters["@tag3"] = "rubyonrails"
Tidak, ini tidak terbuka untuk injeksi SQL. Satu-satunya teks yang disuntikkan ke CommandText tidak didasarkan pada input pengguna. Ini semata-mata didasarkan pada awalan "@tag" hardcoded, dan indeks array. Indeks akan selalu menjadi bilangan bulat, tidak dibuat oleh pengguna, dan aman.
Nilai yang dimasukkan pengguna masih dimasukkan ke dalam parameter, jadi tidak ada kerentanan di sana.
Sunting:
Selain masalah injeksi, perhatikan bahwa menyusun teks perintah untuk mengakomodasi sejumlah parameter variabel (seperti di atas) menghalangi kemampuan server SQL untuk memanfaatkan kueri yang di-cache. Hasil akhirnya adalah Anda hampir pasti kehilangan nilai menggunakan parameter di tempat pertama (sebagai lawan hanya memasukkan string predikat ke dalam SQL itu sendiri).
Bukan berarti paket kueri yang di-cache tidak berharga, tetapi IMO kueri ini hampir tidak cukup rumit untuk melihat banyak manfaat darinya. Sementara biaya kompilasi mungkin mendekati (atau bahkan melebihi) biaya eksekusi, Anda masih berbicara milidetik.
Jika Anda memiliki RAM yang cukup, saya berharap SQL Server mungkin juga akan meng-cache rencana untuk jumlah parameter yang umum. Saya kira Anda selalu dapat menambahkan lima parameter, dan membiarkan tag yang tidak ditentukan menjadi NULL - rencana kueri harus sama, tetapi tampaknya sangat jelek bagi saya dan saya tidak yakin itu sepadan dengan optimasi mikro (walaupun, di Stack Overflow - ini mungkin sepadan).
Selain itu, SQL Server 7 dan yang lebih baru akan membuat parameter kueri secara otomatis, jadi menggunakan parameter tidak terlalu diperlukan dari sudut pandang kinerja - namun, penting dari sudut pandang keamanan - terutama dengan data yang dimasukkan pengguna seperti ini.