C# SQL参数化查询。添加不必要的参数

C# SQL参数化查询。添加不必要的参数,c#,sql-server,parameters,C#,Sql Server,Parameters,我在一个项目中使用参数化查询来防止SQL注入,我遇到了一个有趣的查询场景。我有一个查询,它有时比其他查询具有更多的参数,即where子句更改。以下两个代码块在性能或其他方面是否有任何差异?此代码位于对象内部,因此“变量”是属性,并且两个方法都具有访问权限 在本例中,我仅在满足条件的情况下添加参数 public bool TestQuery() { SqlCommand command = new SqlCommand(); string query

我在一个项目中使用参数化查询来防止SQL注入,我遇到了一个有趣的查询场景。我有一个查询,它有时比其他查询具有更多的参数,即where子句更改。以下两个代码块在性能或其他方面是否有任何差异?此代码位于对象内部,因此“变量”是属性,并且两个方法都具有访问权限

在本例中,我仅在满足条件的情况下添加参数

    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();
    }
    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();
    }
在本例中,我每次都添加所有参数,并且仅在满足条件时添加where子句参数

    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();
    }
    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();
    }

根据我做的测试,它们中的任何一个都可以工作。我个人更喜欢第二个,因为我觉得它更干净,更容易阅读,但我想知道是否有性能/安全方面的原因,我不应该添加未使用的参数,这些参数可能会是null/空字符串。

我想我会根据哈博的评论选择一个选项,因为beargle的答案在我的系统中不起作用情况..

第一选择是我的偏好。它将参数与使用它们的代码保持在一起,并且会使无意中引用参数变得更加困难,例如,当某人正在进行维护时。它还避免了如何填充参数的问题,这些参数可能没有值(或者获取值很昂贵),但不会在查询中使用。一般来说,性能和安全性都不会受到任何影响。如果代码被修改为允许SQL注入,聪明的(ab)用户可以访问任何提供的参数,即使您不使用它们。