プロジェクトでパラメーター化されたクエリを使用して SQL インジェクションを防止していますが、クエリで興味深いシナリオに遭遇しました。場合によっては他のパラメーターよりも多くのパラメーターを持つクエリがあります。つまり、where 句が変更されます。次の 2 つのコード ブロックの間に、パフォーマンスまたはその他の点で違いはありますか? このコードはオブジェクト内にあるため、「変数」はプロパティであり、両方のメソッドにアクセスできます。
この例では、条件が満たされた場合にのみパラメーターを追加します。
public bool TestQuery()
{
SqlCommand command = new SqlCommand();
string query = GetQuery(command);
command.CommandText = query;
//execute query and other stuff
}
private string GetQuery(SqlCommand command )
{
StringBuilder sb = new StringBuilder("SELECT * FROM SomeTable WHERE Active = 1 ");
if (idVariable != null)
{
sb.Append("AND id = @Id");
command.Parameters.Add("@Id", SqlDbType.Int).Value = idVariable;
}
if (!string.IsNullOrEmpty(colorVariable))
{
sb.Append("AND Color = @Color");
command.Parameters.Add("@Color", SqlDbType.NVarChar).Value = colorVariable;
}
if (!string.IsNullOrEmpty(sizeVariable))
{
sb.Append("AND Color = @Size");
command.Parameters.Add("@Size", SqlDbType.NVarChar).Value = sizeVariable;
}
return sb.ToString();
}
この例では、毎回すべてのパラメーターを追加し、条件が満たされた場合にのみ where 句の引数を追加します。
public bool TestQuery()
{
SqlCommand command = new SqlCommand(GetQuery());
command.Parameters.Add("@Id", SqlDbType.Int).Value = idVariable;
command.Parameters.Add("@Color", SqlDbType.NVarChar).Value = colorVariable;
command.Parameters.Add("@Size", SqlDbType.NVarChar).Value = sizeVariable;
//execute query and other stuff
}
private string GetQuery()
{
StringBuilder sb = new StringBuilder("SELECT * FROM SomeTable WHERE Active = 1 ");
if (idVariable != null)
sb.Append("AND id = @Id");
if (!string.IsNullOrEmpty(colorVariable))
sb.Append("AND Color = @Color");
if (!string.IsNullOrEmpty(sizeVariable))
sb.Append("AND Color = @Size");
return sb.ToString();
}
私が行ったテストによると、それらのいずれかが機能します。個人的には 2 番目の方がクリーンで読みやすいと感じているので、2 番目の方を好みますが、使用されていない、おそらく null/空の文字列になるパラメーターを追加してはならないパフォーマンス/セキュリティ上の理由があるのではないかと思います。