CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Eric Wise

Business & .NET

The Pragmatic Adhoc SQL vs Stored Procedures Discussion

Today Jeremy linked to a post with some amusing comics but ended with a statement that came off to me as anti-stored procedures.  I can already smell the debate of ad-hoc sql in your data layer versus stored procedures so I thought I'd write up a quick post describing why neither party is right, and that the pragmatic developer walks the middle of the road.

 

Stored Procedures Are More Secure

This is the strongest argument for using stored procedures versus ad-hoc sql.  First, you can be sure that no sql injection attacks will ever occur.  In the ad-hoc world you're depending on all developers and accounts that access the database to use parameterized queries.

A bigger reason is that in the ad-hoc world you actually have to grant the user/application the rights to change data in the server directly on the table.  In my very humble opinion this is unacceptable.  Should an account become compromised, the hacker now has rights to do basically whatever they want to your data, which is a bad situation to be in.

 

Stored Procedures (and views) Protect Your Application From Changes

As people jump onto the Agile/Unit Testing bandwagon, I see this common theme about insulating your application from damage from changes.  So when I see people in the TDD crowd slamming stored procedures and views it greatly confuses me.  If you run things though views and stored procedures, you have the power to completely rip out the underlaying data structure and just ensure that the stored procs and views return the new structure's data in the expected format for the application.  Your DBA team can work completely independently of your programming team and do pretty much whatever they want and your application doesn't care!  *gasp* a stored procedure or view is like a contract or interface.

In addition, you can make minor changes to a stored procedure without a recompile/redeploy, unlike ad-hoc.

 

Stored Procedures aren't portable

The biggest weakness.  But only a weakness if you actually do support multiple databases.  Unless you're an ISV or software vendor this is unlikely.  I would wager that the vast majority of developers work with a single database platform.

 

Dynamic Where Clauses Are A Pain in the Ass

Dynamic queries are difficult for programmers to write, and not all that fun to look at when compared to ad-hoc querying.

 

So what do I do?

If I'm designing a system, or you're asking me what I recommend, here's what I do: Both.  Here are my rules of thumb:

  1. As much business logic as possible goes into the code layer, it's job is to scrub the data for the database server.  The database server only enforces ACID.
  2. Anything that changes data is a stored procedure.  Accounts are granted execute on a need be basis to the stored procs.  This way if something is compromised, they still have to play by your rules, limiting the damage.
  3. Reporting, filtering, and otherwise dynamic queries are done with in line/ad-hoc sql but must be executed against views with only select rights granted to the accounts.
  4. The database is designed to filter, sort, and index things far more efficiently than you could ever do on the programming side... let the database do what it does well.

The biggest thing to take away from the above is reducing your attack surface and jealously guarding your data integrity.  Stored procedures and views are the best tools we have for this task.



Comments

Oskar Austegard said:

I couldn't agree more with conclusions/rule of thumb 2 through 4.  Conclusion 1, however is open for discussion: What if the operation requires checking against other tables, etc in the database?  This sort of business logic/scrubbing is far more efficiently done within a stored procedure than in a BLL which will require multiple roundtrips to the database (via the DAL).
# May 24, 2006 9:15 PM

Eric Wise said:

1 is open for discussion indeed.  But the definition of ACID suggests that in order to maintain atomicity, consistency, isolation, and durability that there will be instances where business logic will bleed into the database layer.  This is a point many people take exception to but it is a fact of life.  As you point out the alternative of many round trips and many methods being called isn't desirable.  In fact I would suggest that that technique is more likely to introduce errors than doing the checks in the database tier within a transaction.

Consider that as soon as you pull say, relational data out into your business layer and start checking relations/etc that data still exists on the server, if some other process comes in and modifies or blows that data away you're holding old or bad data.  Naturally there are ways of detecting this and aborting it but none are as easy or efficent as smart record locking in the database tier.

# May 24, 2006 9:53 PM

Po said:

I suspect the reluctance to embrace stored procs comes down to either apathy or unfamiliarity. It took me a while to cross from inline SQL to using stored procs and to me now its a no brainer. What I'd like to see is an article that addresses some of the hurdles with using procs that are easier to slap together with inline SQL, eg dynamic sql.
# May 24, 2006 10:03 PM

karl said:

Some of the commenters in "Have I inherited a disaster" took exception to my pro-stored procedure stance.  I called in-liners lazy (although there is some context around that). I guess I need to see examples of this pure OO adoptions 'cuz for the life of me I can't imagine going without them...
# May 24, 2006 11:15 PM

Frans Bouma said:

"This is the strongest argument for using stored procedures versus ad-hoc sql.  First, you can be sure that no sql injection attacks will ever occur.  In the ad-hoc world you're depending on all developers and accounts that access the database to use parameterized queries."
You start with this statement. Now, I've participated in a couple of these debates (as some of you might remember ;)) and after this statement I already read enough. Eric, the first thing you've to do when you stirr up this useless debate is: really know what you're saying in every word you're saying. Not that you're not qualified to stirr up this discussion, but you make a big mistake here: A stored procedure isn't a guarantee SQL injection doesn't occur. There are a lot of 'search' stored procs out there which simply concatenate SQL inside the proc. That's as insecure as ad-hoc-non-parametric-SQL, however just because it's inside a proc, it looks like it's safe. It's not. I know you likely didn't mean that, but it might occur for the reader that you did mean that.

People also forget that there are 3 types of doing sql:
- procs
- ad-hoc querying using value concatenation
- dyn. sql using parameters, where it's likely the sql is generated on the fly.

Group 2 is often merged with group 3, while that's incorrect. I dislike group 2 as much as the next guy. It's group 3 which has the advantage. For example I never write SQL anymore, that's done for me, by an engine. SciFi? No, it's available for everyone: commercial or free / OSS.
# May 25, 2006 4:36 AM

jlynch said:

Eric,

Even though I'm an advocate of RAD development techniques, I ALWAYS USE SPROCS! I just can't imagine doing it any other way. Even though my business logic does sometimes end up in the sproc rather than the BLL.

Hmmmm... Maybe I'm not such a RAD guy after all!

:) Jeff
# May 25, 2006 8:32 AM

Eric Wise said:

Frans-

Yes, I have greatly enjoyed reading the various debates over the years.  You are correct that concatonating sql is a bad thing no matter where you do it.  It'd be a shame if you stopped reading there since I actually go on to support ad-hoc parameterized queries for "dynamic wheres" against views for reporting, lists, etc.  ;)

I personally feel that the more important debate point is the attack surface in your application and how stored procedures for changes and views for read only access improve your security, consistency, and reliability by a ton over a pure ad-hoc solution.

Jeff-
Sprocs can be RAD =)  I actually use Codesmith to generate the basics to get me started then tweak things out from there.
# May 25, 2006 9:18 AM

Jeff Gonzalez said:

I have been involved in some discussions (arguments?)  with Frans over this very thing before.  We still use stored procedures at work, mainly because it allows a DBA to tune performance as needed, instead of a developer.

There are DEFINITELY some maintenance issues around stored procedures even if you use code generation.  We generate a set of stored procedures and preprend them with a special character.  This lets us know that this is a "generated" stored procedure.  No human should ever modify that sproc directly (unless it has been regenerated), this has cut down tremendously on the amount of maintenance we have to do, but not all of it.

The problem really becomes that if you have an actively generated architecture, where you depend on being able to re-generate your data objects at compile time (during a build for instance).  You also cannot use or consume the stored procedures anywhere except through generated code, because it will create an external dependancy that you will have to update manually.  Which is probably the reason you got into code generation in the first place =)

Stored Procedures are not an end-all, be-all solution, but they are useful for seperating developers and DBA responsibilities.
# May 25, 2006 9:52 AM

Jeremy D. Miller -- The Shade Tree Developer said:

I promised myself that I wouldn't ever make another post about stored procedures, but Eric's post on...
# May 25, 2006 3:47 PM

John Wood said:

It's easy to think there are two types of programmers in this world - those who are for using stored...
# May 25, 2006 9:00 PM

Snoop Blogg - The Bloggfather said:

Frans Bouma summarizes a war that has been brewing since the popularity of ORMapping and Code Generation....
# May 26, 2006 9:37 AM

Bob Archer said:

SP's being more secure is a myth! Your suggestion is that SP's be used for all data changes and access via Views. But, if as you suggest someone gains access to the Views they play by "your" rules. Well, can't they do any select against those views. Isn't that really the risk here. I don't care what some bad guy changes, backups protect from that. It is the data that they can extract, customer list, credit card numbers, ssns, etc that is what you should be worried about.

This is why you should not use SQL Server security. You should use NT Athentication or whatever they are calling it now. Since most enterprise apps these days are web/n-tier it is only the process account that is given access to the Db. These accounts can be set up so that only windows even knows what the password is. So, they are very hard to break.

People are your weekest security point and biggest attach surface area.

I am constantly amazed at the number of customers I deal with that run "our" app connecting with "sa" and no password. In this case, it doesn't matter if you use SP's, Views, rubber bands and chewing gum.

Your biggest security risk is not people cracking some Windows/SQL user id, it is them getting one of your users week passwords through social engineering. This is a much bigger threat and easier attack surface.

***********

Since security is the biggest SP card carrying members argument if you remove it what do you have.

SQL Injection - can happen in SP's as Frans pointed out.

Performance - nope, even MS says they are treated no differently than ad-hoc queries. They can actually be more performant since with dynamic queries there is a better chance of a more focused query which will have a much better execuction plan.

Protection from Changes - ever hear of O/R mappers?

'nuff said...

(Disclaimer: based on SQL Server stuff, other db security may be better than SQL logins.)

BOb

# May 26, 2006 10:00 AM

Bob Archer said:

John:

You didn't finish...

Those that use stored procedures and those that wish the didn't!

BOb
# May 26, 2006 10:01 AM

johnwood said:

Bob,
That's a trackback to my post:
http://dotnetjunkies.com/WebLog/johnwood/archive/2006/05/25/stored_procedures_good_bad.aspx

CS isn't very good at showing trackbacks in comments unfortunately.
John
# May 26, 2006 10:07 AM

Williams said:

Maybe a stupid question : source-control
How do you get the stored procs also in your source control,
at the same time you do a check in?
With ad hoc SQL, it is in the source, no problem there.
With stored procs, this code is on the database, and not a text file.
I know the database layout should also be in source control,
but database layout is rather fixed, and when a DBA changes the database, he can easily get the changes also in source control.
Source code or SQL changes a lot more than database layout.
# May 27, 2006 2:05 AM

Eric Wise said:

There is a database project type in Visual Studio.  You can put all your stored procedure scripts in there and execute them to update any server at will using a data connection.

DBAs I know really like this feature and are willing to use the database project in visual studio to do their edits.
# May 27, 2006 11:26 AM

Craig's Blog said:

I recently have been following two arguments on Codebetter.com.  One is the classic stored procedure...
# May 27, 2006 1:13 PM

Craig's Blog said:

I recently have been following two arguments on Codebetter.com.  One is the classic stored procedure...
# May 27, 2006 1:16 PM

Peter's Gekko said:

Last week another rant on stored procs in databases passed by. A lot on it has been said over and over...
# May 29, 2006 9:35 AM

Chris said:

I know this is an old post but i just ran into another scenerio that I am currently having to rethink my stance on Stored Procs.  The main issue I am having with the project I am on is that the original application has mutliple versions.  They use the same stored proc for each of these versions and pass in @ver to each and every stored proc.  Then have a bunch of if statements to change the behavior.

If I move this code into the applicaton via an embedded resource I can keep the parameterized query, query formatting and remove the version issue.   This helps greatly.

If the middle tier is accessing the database using nt auth then you have no security issue you mention.

# November 17, 2006 12:15 PM

Hilton Giesenow's Jumbled Mind said:

WARNING & DISCLAIMER: This is a long post, split over a series, as it discusses some old, well-entrenched

# February 1, 2008 6:49 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!