každý můžete parametrizovat hodnotu, takže něco jako:
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]);
}
}
Což vám dá:
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"
Ne, toto není otevřené pro SQL injection. Jediný text vložený do CommandTextu není založen na vstupu uživatele. Je založen výhradně na pevně zakódované předponě „@tag“ a indexu pole. Index bude vždy být celé číslo, není vygenerováno uživatelem a je bezpečné.
Hodnoty zadané uživatelem jsou stále nacpané do parametrů, takže zde není žádná zranitelnost.
Upravit:
Pomineme-li obavy z injekce, všimněte si, že sestavení textu příkazu tak, aby vyhovovalo proměnlivému počtu parametrů (jak je uvedeno výše), brání SQL serveru ve schopnosti využívat dotazy uložené v mezipaměti. Čistým výsledkem je, že téměř jistě ztratíte hodnotu používání parametrů na prvním místě (na rozdíl od pouhého vkládání predikátových řetězců do samotného SQL).
Ne, že by plány dotazů v mezipaměti nebyly cenné, ale IMO tento dotaz není ani zdaleka tak komplikovaný, aby z něj bylo vidět mnoho výhod. I když se náklady na kompilaci mohou přiblížit (nebo dokonce překročit) náklady na provedení, stále mluvíte o milisekundách.
Pokud máte dostatek paměti RAM, očekával bych, že SQL Server pravděpodobně uloží do mezipaměti plán pro běžné počty parametrů. Předpokládám, že byste mohli vždy přidat pět parametrů a nechat nespecifikované značky být NULL - plán dotazů by měl být stejný, ale zdá se mi to docela ošklivé a nejsem si jistý, zda by to stálo za mikrooptimalizaci (ačkoli, na Stack Overflow – může to stát za to).
SQL Server 7 a novější také automaticky parametrizuje dotazy, takže použití parametrů není z hlediska výkonu ve skutečnosti nutné – je však kritické z bezpečnostního hlediska – zejména s daty zadávanými uživateli, jako je tato.