1

I'm using Dapper in my project. Very often there are situations when I need to change the SQL query depending on some variables.

For example:

public override QueryResult Handle(Query query) 
{
    var sql = "SELECT field FROM table";

    if(someModel.IncludeSomething){
        // add inner join something + add SELECT something.field
    }

    if(conditionN){...}

    return Connection.Query<QueryResult>(sql, query);
}

How do you work with dynamic SQL queries in your projects?

2
  • For this purpose very good ORMs such as EF/linq2db. Commented Sep 28, 2017 at 23:05
  • I agree, Linq2db is great, as fast as dapper, and with linq support, I don't know why it is not recommended. You can create dynamic querys. Commented Jun 25, 2018 at 3:32

3 Answers 3

5

I had the same situation, to develop custom dashboards/reports with dynamic filters, grouping, and sometime with the need to join with other tables.

Since the Stored Procedures approach don't play nicely in such case, I have developed my own library SqlKata, a dynamic query builder that offer the above requirements, without sacrificing with the security and performance, since it uses the Parameters Binding technique. check it out and hope you will find it helpful :)

Sign up to request clarification or add additional context in comments.

Comments

1

Leaving aside the performance issue (which may or may not be), I use several approaches depending on what's the simplest yet maintainable.

  1. Create views / stored procedures which fit the DSL (domain specific language) better. This should reduce the need of dynamic SQL
  2. If option 1 is not feasible, then you can use an ORM (not great for high performance or maintainable complex queries) or a data mapper with typed support for building such queries. I use my own SqlFu which features a strongly typed query builder which allows conditionals, as long as you query one table/view/stored procedure
  3. Very often a combination of 1 and 2.

If you need to create queries involving joins dynamically, it might be a hint of improper design and a strong maintenance smell. I would say to think it again and find a way to refactor it.

Personally, I didn't encounter a problem that couldn't be solved with options 1-2, but maybe your reporting requirements are way more complex than mine.

Comments

1

I do my best not to dynamically construct SQL queries. I have come aboard projects several times that do this, and it has always been a source of trouble. Compared to stored procedures, dynamically constructed SQL will incur query parsing and planning costs much more often, will incur higher data transmission costs always, and are much more likely to result in unforeseen, unwieldy, unperformant, and otherwise problematic queries. Basically, this approach is guaranteed not to scale.

Instead, if at all possible, maintain a set of tuned stored procedures that collectively cover your query space. In some cases, the applicable stored procedure will be more general than you require (e.g. have a "WHERE [Foo] = @foo OR @foo IS NULL" clause that you could have left off entirely if you knew that the query was never going to match on Foo). Either accept that cost or write a specialized stored procedure for situations when the more general stored procedure becomes a bottleneck.

If you ignore my advice and do construct SQL dynamically, then at very least use parameters instead of values wherever you can. If you construct "WHERE [Foo] = 1" for one query and "WHERE [Foo] = 2" for another, both queries will be compiled separately. If instead you construct "WHERE [Foo] = @foo" for both and pass @foo = 1 for the first and @foo = 2 for the second, then you will at least just incur the compile cost once and the cached query plan will be used for the second call.

2 Comments

As a footnote, code consolidation in a stored procedure could also support dynamically created and executed queries. I've run into issues where a user interface contained a multitude of parameters (especially, optional ones), which would be more easily implemented using dynamic SQL statements. However, doing so outside of a stored procedure, would/could present SQL Injection vulnerabilities. The answer (for me) was passing Key/Value pair parameters to a stored procedure, validating each, then creating and executing the SQL within the same or another stored procedure.
This simplified maintenance (centralized) and reduced vulnerabilities, although some performance (speed) loss may have been a compromise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.