C# SQL复杂数据搜索查询

C# SQL复杂数据搜索查询,c#,sql,sql-server-2008,C#,Sql,Sql Server 2008,我正在使用c.NET 我有3个字段文本框txtName、txtSirname、txtLocation 我的数据库表是 Name | Sirname | Location Steve | Jobs | US Kevin | Peterson | UK Haechelle | Gibbs | South Africa 我有一个搜索按钮。点击搜索按钮,我想根据文本框X显示所有结果 但是 如果所有的文本框都是空的,我想显示整个表格。 如果名称为空,则应根据名

我正在使用c.NET

我有3个字段文本框txtName、txtSirname、txtLocation

我的数据库表是

Name      | Sirname  | Location

Steve     | Jobs     | US
Kevin     | Peterson | UK
Haechelle | Gibbs    | South Africa
我有一个搜索按钮。点击搜索按钮,我想根据文本框X显示所有结果

但是

如果所有的文本框都是空的,我想显示整个表格。 如果名称为空,则应根据名称和位置显示结果。 如果sirname为空,则应根据名称和位置显示结果。 如果name和sirname为空。。。以及所有可能的组合

我的问题是不允许在C中使用if语句。我必须只在一个SQL查询中编写它。我该怎么做呢。请告诉我。

使用

WHERE     
    ([Name] = @name OR @name IS NULL) OR
    ([Sirname] = @sirname OR @sirname IS NULL) OR
    ([Location] = @location OR @location IS NULL)
如果文本框为空,则将NULL作为查询/存储过程中的参数值传递。

使用

WHERE     
    ([Name] = @name OR @name IS NULL) OR
    ([Sirname] = @sirname OR @sirname IS NULL) OR
    ([Location] = @location OR @location IS NULL)
select ... from ... where
    name = isnull(nullif(@name, ''), name) and
    sirname = isnull(nullif(@sirname, ''), sirname) and
    location = isnull(nullif(@location, ''), location)
如果文本框为空,则将NULL作为查询/存储过程中的参数值传递

select ... from ... where
    name = isnull(nullif(@name, ''), name) and
    sirname = isnull(nullif(@sirname, ''), sirname) and
    location = isnull(nullif(@location, ''), location)
只要在需要忽略参数时传递null或空字符串即可。它假定:@name、@sirname和@location是参数

只要在需要忽略参数时传递null或空字符串即可。它假定:@name、@sirname和@location是参数

嗯。他告诉我,出于性能原因,我应该避免10个if,并为其编写一个查询

他完全错了。如果您通过TSQL中处理每个组合的拼凑查询来实现这一点,那么该查询将执行得非常次优,并且将特别容易受到参数嗅探的性能痛苦的影响

坦率地说,我会忽略他,用C代码编写正确的查询——这几乎是瞬间的,就像:微秒——要求数据库服务器运行错误的TSQL查询是非常昂贵的。例如,以下是原始TSQL中累积过滤器的完整实现:

static void AppendClause(StringBuilder clause, string tsql)
{
    clause.Append(clause.Length == 0 ? " where " : " and ")
          .Append('(').Append(tsql).Append(')');
}    
static Foo[] SearchFoo(string name, int? age, string region)
{
    var whereClause = new StringBuilder();
    if (name != null) AppendClause(whereClause, "f.Name=@name");
    if (age != null) AppendClause(whereClause, "f.Age=@age");
    if (region != null) AppendClause(whereClause, "f.Region=@region");

    string tsql = "select f.* from Foo f" + whereClause;
    using (var conn = GetConnection())
    { // note I'm using "dapper" here for brevity, but any ADO.NET-based
      // code would suffice
        return conn.Query<Foo>(tsql, new { name, age, region }).ToArray();
    }
}
或与LINQ中的相同:

static Foo[] SearchFoo(string name, int? age, string region)
{
    using (var ctx = GetContext())
    {
        IQueryable<Foo> query = ctx.Foos;
        if(name != null) query = query.Where(f => f.Name == name);
        if(age != null) query = query.Where(f => f.Age == age);
        if(region != null) query = query.Where(f => f.Region == region);
        return ctx.ToArray();
    }
}
你的同事大错特错了。如果他仍然不同意,请随时向他指出我的方向;p

嗯。他告诉我,出于性能原因,我应该避免10个if,并为其编写一个查询

他完全错了。如果您通过TSQL中处理每个组合的拼凑查询来实现这一点,那么该查询将执行得非常次优,并且将特别容易受到参数嗅探的性能痛苦的影响

坦率地说,我会忽略他,用C代码编写正确的查询——这几乎是瞬间的,就像:微秒——要求数据库服务器运行错误的TSQL查询是非常昂贵的。例如,以下是原始TSQL中累积过滤器的完整实现:

static void AppendClause(StringBuilder clause, string tsql)
{
    clause.Append(clause.Length == 0 ? " where " : " and ")
          .Append('(').Append(tsql).Append(')');
}    
static Foo[] SearchFoo(string name, int? age, string region)
{
    var whereClause = new StringBuilder();
    if (name != null) AppendClause(whereClause, "f.Name=@name");
    if (age != null) AppendClause(whereClause, "f.Age=@age");
    if (region != null) AppendClause(whereClause, "f.Region=@region");

    string tsql = "select f.* from Foo f" + whereClause;
    using (var conn = GetConnection())
    { // note I'm using "dapper" here for brevity, but any ADO.NET-based
      // code would suffice
        return conn.Query<Foo>(tsql, new { name, age, region }).ToArray();
    }
}
或与LINQ中的相同:

static Foo[] SearchFoo(string name, int? age, string region)
{
    using (var ctx = GetContext())
    {
        IQueryable<Foo> query = ctx.Foos;
        if(name != null) query = query.Where(f => f.Name == name);
        if(age != null) query = query.Where(f => f.Age == age);
        if(region != null) query = query.Where(f => f.Region == region);
        return ctx.ToArray();
    }
}

你的同事大错特错了。如果他仍然不同意,请随时向他指出我的方向;p

这似乎是一个奇怪且武断的规则,在C中不使用if-就我个人而言,我会反驳这一点…是的。我在谷歌上努力搜索,但没能找到。他告诉我,这将提高绩效;例如,看到Jakub的答案只会导致更差的性能。是的,我看到了,但他问我这里有三个文本框txtname,txtSirname,txtLocation如果有十个文本框,你会怎么做。根据他的说法,如果我们对十个文本框进行排列和组合,会有很多if条件。那么他编码不对。如果有10个文本框,将有10个或11个If条件…这似乎是一个奇怪的和武断的规则,在C中不使用If-个人来说,我会推回这一点…是的。我在谷歌上努力搜索,但没能找到。他告诉我,这将提高绩效;例如,看到Jakub的答案只会导致更差的性能。是的,我看到了,但他问我这里有三个文本框txtname,txtSirname,txtLocation如果有十个文本框,你会怎么做。根据他的说法,如果我们对十个文本框进行排列和组合,会有很多if条件。那么他编码不对。如果有10个文本框,那么如果条件是…+1,那么可能会有10个或11个文本框,因为它回答了这个问题,但我强烈建议在实际代码中不要这样做;我看到优化器将这种类型的查询搞得一团糟。在我看来,最好的方法就是简单地为工作构建正确的查询。此外,外部ORs可能希望这样做,并且,如果打算填充多个细节限制搜索,而不是扩大搜索范围的话。多谢老兄。这个答案经过一些修改后被我的组长接受了。不知道性能是否正确。但尽管如此,我还是站在安全的一边。谢谢。+1,因为它回答了这个问题,但我强烈建议在实际代码中不要这样做;我看到优化器将这种类型的查询搞得一团糟。IMO,这里最好的方法就是为作业构建正确的查询
结束了填写多个细节会限制搜索,而不是扩大搜索范围。谢谢老兄。这个答案经过一些修改后被我的组长接受了。不知道性能是否正确。但尽管如此,我还是站在安全的一边。谢谢。虽然它不在单个SQL查询中,但我从您的答案中得到了添加where子句字符串的逻辑想法。我会试试这段代码,然后给他看。马克先生,这段代码工作得很好,但是我的团队领导太傻了,他不接受这种编码方式。据他说,我提交的jakub的代码修改方式是正确的。现在不要再做更多的事情了。但thanx需要帮助。@自由职业者,那一定很烦人。顺便说一句,他错了——很容易证明,只要看一下在计划图下执行的两个查询,stats io、stats timening和其他一些。是的,先生,他可能错了。“但我除了听他讲话之外别无选择。”自由职业者我不同意——你也可以展示真实的数字。但这也可能有点对抗性。虽然不是在单个SQL查询中,但我从您的答案中得到了添加where子句字符串的逻辑想法。我会试试这段代码,然后给他看。马克先生,这段代码工作得很好,但是我的团队领导太傻了,他不接受这种编码方式。据他说,我提交的jakub的代码修改方式是正确的。现在不要再做更多的事情了。但thanx需要帮助。@自由职业者,那一定很烦人。顺便说一句,他错了——很容易证明,只要看一下在计划图下执行的两个查询,stats io、stats timening和其他一些。是的,先生,他可能错了。“但我除了听他讲话之外别无选择。”自由职业者我不同意——你也可以展示真实的数字。但这也可能有点对抗性。真的由你决定。