18

I have a web application that communicates with SQL server. Rather than hard-coding all of the query strings, I have opted to store them in a global resource file. Is that considered bad practice?

On a side note, when I do this, Visual Studio yells at me about the possibility of SQL injection, despite those queries being parameterized (not to mention the "spelling" warnings inside the resource file).

Jon Martin
  • 3,252
  • 5
  • 29
  • 45
  • 3
    Why do you have query strings in your app? Shouldn't you be using stored procedures, and your methods would call stored procedures? – Aaron Bertrand Jul 19 '11 at 18:59
  • This is only marginally better than hard coding the queries into your .cs or .vb files - which is to say it's not very good design. – Yuck Jul 19 '11 at 19:00
  • 1
    Unfortunately I don't have the luxury of using stored procedures for this application. Is there another way I can go about this? – Jon Martin Jul 19 '11 at 19:02
  • 1
    Just remember, parameterized queries are only safer in a stored proc / sql if you do NOT dynamically exec or concat the results. If you pass a string as a parameter and then go and do something like AND FOO='+@myvar or whatever, it's still a problem. I do see this sort of thing, unfortunately. – Nikki9696 Jul 19 '11 at 19:42

9 Answers9

12

Practices fall into a range (e.g. Avoid, Prefer, Use, etc.) and depend on context.

If you have a mandate from on high that stored-procs shalt not be used and neither shall ye use an ORM, then storing your complex SQL as a resource is not that bad of a practice because you at least don't have to escape characters in a System.String and you at least keep it somewhat safe from eyes. If your SQL is dynamic in nature, combining resource files with a text templating mechanism is fairly clean.

That said, generally (i.e. it seems in most contexts) using resource files should be avoided unless there's a clear benefit in maintenance costs, readability, and capability. There are quite a few clean ways to bind stored procedures to code; there are a number of competent ORM tools and mini-data access layers (aka micro-ORMs in today's parlance) that might do a better job.

Kit
  • 20,354
  • 4
  • 60
  • 103
  • 6
    Why should resource files generally be avoided? – stakx - no longer contributing Oct 24 '14 at 18:36
  • 1
    Years later... the reason resource files should be avoided is that there are simply better ways to do SQL from imperative code, such as classic ADO.NET parameterization, a micro-ORM or ORM. The resource file is a bit more of an overhead from a maintenance perspective. – Kit Jul 08 '19 at 14:29
  • Agreed. Last time I dealt with this kind of thing (about 3 years ago), I also ended up writing parameterized ADO.NET SQL queries inline. The resource files felt like an unnecessary overhead. +1 also for taking the time to reply. ;-) – stakx - no longer contributing Jul 09 '19 at 19:20
9

Having the SQL queries separated from the application code is a good thing. Stored procedures is the normal way to do this, but if that's not feasible and you have to use SQL directly I think your approach is good. With recent versions of SQL server parameterized queries are precompiled the first time they are run and give similar performance to an SP.

I would however advise you to look into other data access methods such as linq-to-sql which automates the SQL query generation and gives you a cleaner interface in the code.

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
7

Resource files are definitley not the place for this. The point of resource files is to be a centralized repository for things that can be localized (i.e. overridden by other resource files that are defined for other languages/cultures).

For example, you'd put a string "Hello" in a X.resources.dll, but then you could also create a es-ES\X.resources.dll for Spanish, in which the string would say "Hola" instead — then when your application queries for the string, it will get whatever version matches the language/culture of the user's operating system configuration.

If you want your SQL to be easily changed without recompilation of code, put it in your App.config and use the ConfigurationManager class to read it out. If you don't want it to be changeable without code recompilation, just hard code the thing as a static/const string. That said, the ideal, of course, is to make real stored procedures.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
Robert Levy
  • 28,747
  • 6
  • 62
  • 94
4

I think many people consider hard coded SQL to be a bad practice regardless of how it is stored... :-)

I'm going to assume that there is some compelling reason for not using Linq to SQL, or Entity Framework, or another ORM tool?

If you must use hard coded SQL in your application, would argue that it is BETTER inline in your code because it makes your code more readable, and therefor more maintainable...

Scrappydog
  • 2,864
  • 1
  • 21
  • 23
4

I've built an application using this pattern - in PHP, not .Net, but the principles are the same.

Benefits:

  • I could easily find all the SQL I needed in a single file. This helped when dealing with database questions (does any part of the app actually use this table? How many queries do we have that update table z?).
  • I could easily update the SQL without changing the rest of the code.

Drawbacks:

  • It made the rest of the code harder to debug - if there was a problem around the data being returned from the database, I had to look in two places. And many of the resource keys were very similar, leading to some entertaining wtf moments.
  • In practice, I never once updated the SQL without changing the rest of the code.

In my experience, the benefits don't stack up against the drawbacks.

BTW - many of those drawbacks also apply to stored procedures. There's a good case for using stored procs - but there's an equally good case for not using them.

Neville Kuyt
  • 29,247
  • 1
  • 37
  • 52
3

I don't see anything particularly "bad" with doing this. It really isn't much different than hard coding the sql code within your code, and only minorly different than generating the SQL ad-hoc at runtime.

You say that you are using parameterized queries, so you shouldn't have to worry about script injection.

If you are storing the sql in a resource file to adhere to the DRY principle, then you may want to use some kind of DAL for that purpose instead. Like Entity Framework (EF) or Linq-to-SQL

Chris Pietschmann
  • 29,502
  • 35
  • 121
  • 166
  • Thanks - I haven't looked into Linq-to-SQL yet. I'll take a look into that, it sounds like it's a better way to go. – Jon Martin Jul 19 '11 at 19:12
  • 1
    Looked into Linq-to_SQL, and while the idea makes a lot of sense it seems like it is quite an extensive framework to learn. The scope of my need is quite a lot smaller than the scope of what Linq-to-SQL is capable of. Having said that, if nothing else comes up I'll give it a go. – Jon Martin Jul 19 '11 at 19:58
1

It is not necessarily bad practice, but it makes it harder to read you program if one needs to open another file and find the right key.

Visual Studio complains because it cannot see that the value is constant and that it always comes from a trusted source.

Having SQL in source files is no more "hard-coding" than having the rest of the program code in the source files. Why are you doing this in the first place? To re-use queries? Maybe you should consider store procedures instead...

Mathias Schwarz
  • 7,099
  • 23
  • 28
0

The thing that comes to mind is that this is simply adding unnecessary complications to the code.

Yes, you could keep the queries in a resource file. Or, to insure that no one messes with them once the project is deployed, you could encrypt them and store them in a file. Or even better yet, you could encrypt them and then store them on a database so that no one who had access to the machine could mess with them.

But eventually, I have to ask, what's the point? Just hard code them and be done with it.

KISS.

Richard
  • 6,215
  • 4
  • 33
  • 48
  • The problem with hard coding them is that it becomes a lot less maintainable that way. – Jon Martin Aug 22 '11 at 19:49
  • What could you possibly do to improve the query once it's been deployed? If that's possible, you should be using views. – Richard Aug 22 '11 at 19:56
  • 2
    @Richard: Fix bugs ;) Suppose you release the app live and one query is accidentally selecting the wrong field. You can just update the query (SP, SQL in a resource file, etc.) and not redeploy the application. – HardCode Aug 23 '11 at 20:48
0

you could write store procedures and call them in your code rather than read the queries stored somewhere outside.

phnkha
  • 7,782
  • 2
  • 24
  • 31