简体   繁体   中英

SQL complex data searching query

I am using c# .NET.

I have 3 fields(Text Boxes) txtName,txtSirname, txtLocation.

My database table is

Name      | Sirname  | Location

Steve     | Jobs     | US
Kevin     | Peterson | UK
Haechelle | Gibbs    | South Africa

I have one search button. On the click of search button i want to display all the results according to text boxex.

BUT

If all the text boxes are empty i want to display whole table. If name is empty then it should disply result according to sirname and place. If sirname is empty then it should display result according to name and place. If name and sirname is empty... and all the possible combinations.

My problem is that i am not allowed to use if statement in C#. I have to write it in one SQL query only. How should i do it. please direct me.

Use

WHERE     
    ([Name] = @name OR @name IS NULL) OR
    ([Sirname] = @sirname OR @sirname IS NULL) OR
    ([Location] = @location OR @location IS NULL)

If your textboxes are empty pass NULL as the value of parameters in your query / sproc.

yeah. he is telling me i should avoid 10 ifs and write a single query for it for performance reason

He is quite simply wrong. If you do that via a cobbled together query in the TSQL that copes with every combination, then that query will perform very sub-optimally (and will will particularly vulnerable to the performance pain of parameter-sniffing).

Frankly, I would ignore him, and write the correct query in the C# code - this will be virtually instantaneous (as in: microseconds) - where as asking a database server to run a bad TSQL query is VERY expensive. For example, here's a complete implementation of a cumulative filter in raw 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();
    }
}

or the same in 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();
    }
}

Your colleague is very mistaken. And if he still disagrees, feel free to point him in my direction ;p

select ... from ... where
    name = isnull(nullif(@name, ''), name) and
    sirname = isnull(nullif(@sirname, ''), sirname) and
    location = isnull(nullif(@location, ''), location)

Just pass null or empty string "" whenever you want to omit parameter. It assumes that: @name , @sirname and @location are parameters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM