Continued...

I finally had some time to address some of the points in Frans post.

 

> Ad-hoc SQL Script is brittle

‘For Ad-hoc queries, you change the query’

Yes, and you’ve also got to recompile the application don't forget to mention that

 

‘A component which generates the SQL on the fly at runtime’

Well this doesn’t really solve the problem does it – it just pushed problem to another layer. Now instead of updating my stored procedures I need to count on returning or executing additional code to dynamically generate the SQL. I’ve also now got more code on the stack that I have to call through to get my data vs. updating a sproc.

 

‘With a stored procedure this wouldn't be possible.’

Why not? For sprocs I can control what fields are returned and I can also control new inputs by defining new parameters that can set default values.

 

> Security

‘Roles’

Frans is making very good points here and we are in agreement. Roles can be used to restrict users to certain tasks, inclusive of SELECT, INSERT, etc. permissions on the database. I tend to think in my limited view of web based applications. In many cases for web based applications you may only need a single user. But, yes, it would be better to define and apply a role for that user – incidentally something we do for managability on www.asp.net.

 

‘in most applications you have 2 roles’

Ever heard of role based security? Frans hasn’t (touché -- sorry couldn't resist :-) ). I think most applications tend to have more than 2 roles, I know mine do :)

 

‘SQL injection attacks due to the parameters’

Totally agree, you can use parameterized ad-hoc SQL to solve this problem. Never said you couldn’t in fact what I said was that stored procedures provide an effective counter-measure, not the only counter measure.

 

> Performance

‘Compiled’

So, I actually did some fact checking and talked to some people on the SQL Server team. Frans' you may be interpreting the documentation incorrectly (or the documentation is wrong, I haven't had a chance to dig through it yet). From what I've been told - again coming from the team that builds SQL Server - is that stored procedures are compiled if the plan is not in the cache. You negelet to mention is that subsequent uses of the stored procedure will use that plan and not compile. My data comes from someone who helped design several stored procedure for a large trading company (called millions of times/day) and the stored procedure was able to stay in the cache and was never re-compiled, quote: 'performance that could never be duplicated with dynamic SQL'.

 

I was also enlighted that the view of the 'data' world affects the design. In a data warehouse/data mart view of the world I was told that dynamic SQL is probably the way to go where a bunch of unrelated sql statements need to be used. In OLTP systems or large data warehouse systems dyanmic SQL is 'not even close' and SPs are the way to go. For example, ad-hoc SQL for complex behaviors will be more resource intensive than stored procedures - take adding a post in the forums (all within a transaction):

1. SELECT - Determine if the forum is moderated?

2. SELECT - If the forum is moderated does the user’s post require moderation?

3. INSERT - Insert post

4. UPDATE - Update related posts with the new child post id

5. UPDATE – Threads table with information about new post

6. DELETE – Clean the table that tracks what posts a user has read

7. UPDATE – If the user is tracking the post, update that a new post has been added

8. Call another procedure to update statistics on the forums

9. UPDATE – Threads statistics

 

I also asked a friend of mine who had a lot of input on a fairly well known and large enterprise resource and planning software package when it was ported to SQL server. His opinion:

‘If the ad-hoc sql is a parameterized statement, then the perf will generally be similar. Otherwise the folks are incorrect - especially if the statement does anything complex such as a join, a sub-query, or anything interesting in the where clause AND the statement happens more than once.  This is to say nothing about other DBA issues such as securing objects, maintenance, abstraction, and reducing network traffic, troubleshooting, etc.’

 

My own conclusions:

  • Both stored procedures and ad-hoc SQL have application maintainability issues. The maintainability is done either in the database or the data abstraction layer, i.e. update a stored procedure, recompile the application, or use an OR mapper. You need to determine where you want to solve this problem, with dynamic SQL it can mean recomilation of the application. With a stored procedure it means an update to the stored procedure.

 

  • Both stored procedures and ad-hoc SQL can address security issues in a similar manner. If you are using ad-hoc SQL, use parameterized statements. Neither has specifc security advantages, although setting permissions only on stored procedures can be easier than individually setting permissions on a resource-by-resource basis.

 

  • Both stored procedures and ad-hoc SQL can be used to solve the same problems and in some cases have equivalent performance. However, stored procedures are better for complex database behaviors such as paging or performing multiple actions either within a transaction or outside a transaction.

 

Thanks Frans, this has definitely proven to be a very valuable discussion! I think the ultimate conclusion is that there are several ways to solve data access problem and everyone should come to his or her own conclusions on what is right for the application. In some cases this is dynamic parameterized SQL (not string concatenation) in others it is stored procedures. However, my personal preference will be to use stored procedures for the majority of data access code, as I still believe the benefits still strongly outweight the costs.

Published Tuesday, November 18, 2003 5:12 PM by Rob Howard

Comments

# re: Continued...

Tuesday, November 18, 2003 6:24 PM by Andrew
The truth doesn't change, it just gets expressed differently to different people at different times.

# re: Continued...

Wednesday, November 19, 2003 12:07 AM by Mark Pitman
"Both stored procedures and ad-hoc SQL can address security issues in a similar manner. If you are using ad-hoc SQL, use parameterized statements. Neither has specifc security advantages, although setting permissions only on stored procedures can be easier than individually setting permissions on a resource-by-resource basis."

One thing that a stored procedure has over ad-hoc sql for security is access to specific records in a table. As far as I know, there is no way for SQL server to enforce business logic security on specific records. So, let's say I have a table that contains performance review information. If a user has select access on a that table, they can get to all of the records in that table if they have query analyzer (or even Excel!). If they do not have select access on that table, but only execute access on a stored procedure that takes credentials as a parameter, they can only access the records that they are supposed to.

# re: Continued...

Wednesday, November 19, 2003 2:23 AM by Frans Bouma
" You negelet to mention is that subsequent uses of the stored procedure will use that plan and not compile. "
What I was trying to correct was the myth that a stored proc is compiled AND the result of that compile is stored in the systables. I believed that for years until I read BOL's articles about that topic. When a proc is created and compiled and that compiled result is stored in the cache is not that important, a production system is not a developer system and a plan is removed from the cache occasionally (see BOL for details on that), plus the dyn. query's plan is cached the first time as well, and kept in the cache until it is moved out for reasons explained in the BOL. So once the proc's plan AND the dyn. query's plan are in the cache, they're both as fast, because all that's done is a plan is taken, parameters are filled in and the plan is re-executed. Dyn. sql matches that speed of the proc.

There are some misinterpretations sneaked into the conversation perhaps: when I talk about a dyn. query I ALWAYS talk about a parametrized query executed using the SqlClient .NET provider. This makes sure sp_executeSQL is used and a plan IS cached, always. queries with values baked into them are not that cacheable for obvious reasons, let's not confuse the two :)

" In OLTP systems or large data warehouse systems dyanmic SQL is 'not even close' and SPs are the way to go."
Why? Dyn. queries contain the same SQL as the proc does. Why are they slower and 'not even close' ? I admit, calling an action stored proc which does a lot of maintenance behind the scenes is sometimes nice to have, but keep in mind that when a connection is open, the statements batched together and send to the server as dyn. queries can do that management too, without slowdowns most of the time due ot the plan caching.

Your example of adding a post to the forum is nice, but I don't see why I should use sprocs for that per se. After all: if I do that using dyn. queries, I use a transaction of ADO.NET, which is nothing more than a BEGIN TRAN execution on the connection, all statements executed on the connection are running inside that transaction, same thing. WHy would it be more resourceintensive? Because of the external transaction management? I don't think so, Sqlserver does the transaction management per connection anyway: there are no nested connections possible.

"If the ad-hoc sql is a parameterized statement, then the perf will generally be similar. Otherwise the folks are incorrect - especially if the statement does anything complex such as a join, a sub-query, or anything interesting in the where clause AND the statement happens more than once."
True, that's why I said: use parameters. :)

While I think it's more than just personal preferences, I can live with the conclusions you mention. :) My point was to enlight another option in the choice what to choose: ad-hoc string contatenation with values vs. stored procedures, and why. I get a lot of questions of people why I don't use sprocs in my O/R mapper because they have to or want to. Most of the time, it turns out they don't know about dyn. created queries with parameters and the benefits of them (or better: that they do not suck as some myths say). It's good that developers out there know all the options they have and what the real pro/con's are of these options so they can make the right choice.

# re: Continued...

Wednesday, November 19, 2003 2:26 AM by Frans Bouma
Oh, I forgot: about the 2 roles I mentioned :) That was an example of a typical webapp. When you follow MS' security guidelines for a webapplication/webserver and you use a separate SQLServer, you can't use domain security (IIS shouldn't run on a server in a domain) so you can only use sqlserver security. MOst of the time, 1 user is used to connect to the database (or a very few, since each user requires a different connection string). This implies not a lot of roles.

In an intranetapp / winforms app with NT security this is of course a different story.

(And I didn't know you were part of rolebased security group for whidbey, really :))

# re: Continued...

Wednesday, November 19, 2003 2:29 AM by Frans Bouma
Mark: define a view on that table, filtering out the rows (or columns).

Views are there for this purpose. (and others, but this purpose is a big plus for views).

Views are not widely used, which is a shame, because views are great and can narrow down the complexity of a query (which will still be complex when the view's code is placed into the query, which is done at runtime (sqlserver).)

# re: Continued...

Wednesday, November 19, 2003 3:59 AM by Crazy Chess Player
What about user defined function which return tables (sql 2000).
Should we use it Frans,
or we should buy your LLBLGEN Pro.



# re: Continued...

Wednesday, November 19, 2003 8:28 AM by Mark Pitman
"define a view on that table, filtering out the rows (or columns)."

Wouldn't I have to create a view for each user of the system? That doesn't sound like such a good option.

# re: Continued...

Wednesday, November 19, 2003 9:06 AM by Thomas Tomiczek
::Wouldn't I have to create a view for each
::user of the system?

What with a SP?

Wouldn't that mean a SP for every user of the system?

If your answer is no here, then basically - to the same thing you do in the one SP i nthe logic of the view.

# re: Continued...

Wednesday, November 19, 2003 9:07 AM by Frans Bouma
"Wouldn't I have to create a view for each user of the system? That doesn't sound like such a good option."
And with a single stored procedure you would be able to do that? You would not, unless you would accept some sort of 'UserId' input parameter, so you can base your filtered rows on that userid (or rights based on that user id).

When you do that, the whole security point is moot, because anyone with QueryAnalyzer can execute that proc with any given userid.

# re: Continued...

Wednesday, November 19, 2003 10:16 AM by Mark Pitman
"because anyone with QueryAnalyzer can execute that proc with any given userid"

In my original post I said "...execute access on a stored procedure that takes credentials as a parameter...". By "credentials" I mean you would have to pass something in to the proc to prove who you are, not just a userid. Whether that is the userid and password, passing in some sort of temporary token based on the user being authenticated by some other method, or something else.

I am NOT saying that everyone should use stored procedures everywhere, all I am pointing out is one example of where I think a stored procedure would be a better solution. If you aren't worried about someone with query analyzer looking at data, then it doesn't matter.

# Stored Procs or Dymanic SQL

Wednesday, November 19, 2003 2:06 PM by TrackBack
So yesterday a debate surfaced that seemed to have the entire online programming community all worked up. Rob Howard, Microsoft ASP.NET Program Manager, posted to his blog about using stored procedures in SQL server. Many comments both for and against Rob's arguments in his post ensued. Things got a little heated when Frans Bouma stepped into the debate. Frans took his ideas to his own blog, and then you see the entire blogging community step in (via their own respective blogs) to add their own take on things. What a day.

# re: Continued...

Wednesday, November 19, 2003 9:56 PM by Curious Proc Guy
Just a quick question, say you had a large table, and you wrote a proc that took an employee id and pwd and the row id to delete from the table. The proc checks if you have access to delete the row, then deletes it. How do we do that with dynamic sql and not give the user access to delete any row he wants, without creating a view for every user?

# re: Continued...

Thursday, November 20, 2003 12:05 AM by Thomas Tomiczek
::How do we do that with dynamic sql and not
::give the user access to delete any row he
::wants, without creating a view for every
::user?

This is called object oriented programming.

The user never issues the SQL, but mnanipulates objects. The object would realize the call is not authorized.

Next step, security wise, us introducing a server for the objects.

And then you talk about a system like an O/R mapper such as our EntityBroker, but one with a client/server version (such as the EntityBroker 2004)

# re: Continued...

Thursday, November 20, 2003 7:12 AM by Philip Rieck
While I'll not take a direct stance on sp vs. dynamic sql (wishy-washy, I know), I do want to mention my favorite pro-stored proc tidbit here.

Where I'm at we have a SQL DBA team. It's their job to be experts at things like performance (and security, but I'll just mention performance benefits here). If I use dynamic sql in my code, they'll try to make sure the database is well tuned and performant, and give some feedback on what to change based on what I tell them I'm trying to do. (If I'm using a dynamic sql generation engine, hopefully I can modify it so that it will allow for these special case tunings.)

If I use a stored procedure, they can do more. They can analyse the input, effects, and output of the procedure when they detect a problem (without my input if need be), then rewrite the stored proc to do the same thing, only faster. They can even modify tables / views it relies on, and keep the output of the sprocs constant... my application never knows.

You can't beat the performance given to you by a great DBA hand-tuning your most-used procs. If you think dynamic sql generation engines can, then I'll take that challange. (well, I'll try to find a great DBA willing to take that challange. Most likely, they will just laugh)

In some (most?) organizations, you may not have this. However if you DO have a good DBA team - use them!

# re: Continued...

Friday, November 21, 2003 12:02 AM by Jon Galloway
Very much agree with Philip's post - you can't tune dynamic SQL without a recompile. The problem is that things don't slow down until everyone's forgotten about the code, or even moved to a different development platform. If you're using SP's, your database access can be tuned independently of the code. I've been through this - a development team I was on had to crack open an old powerbuilder app because the embedded SQL was generally inefficient.

Developers often think about their the database as a consumer instead of as a client - the app is fast enough, so everything may be fine. We get focused on our immediate problem or project, and don't think long term. Of course dynamic SQL is easier, but it's rarely as maintainable.

Two more SP benefits:
1) Common code - just as object oriented design strives to eliminate code duplication, using SP's for DB access provides common database access routines for the entire company. Fewer lines of code means easier maintenance.

2) Easier dependency analysis - I ran into this a week ago. We were looking at a table and wondering what would change if we altered a datatype. If we knew only SP's were hitting it, we could easily determine dependencies right in SQL Enterprise Mgr. But then we remembered that some apps use dynamic SQL and that went out the window...

# re: Continued...

Saturday, November 22, 2003 5:30 AM by Thomas Tomiczek
::If I use a stored procedure, they can do
::more. They can analyse the input, effects,
::and output of the procedure when they detect
::a problem (without my input if need be),
::then rewrite the stored proc to do the same
::thing, only faster

They can NOT. In the vast majority of situations the SP will do very linear things. At least when you follow common practices on programming your business logic into a business layer, not into the database.

On a simple "Insert", "Delete", "Select" there is just that much a dba can optimize.

On a complex SELECT, there is yet again only so much a dba can do - unless the SQL is totally stupid, and this is a generator error.

Mostly the only thing DBA's can really do to boost performance in this environment is: selecting indices.

And this is totally orthogonal to the SQL.

Naturally, for Oracle people this is different, due to Oracle's well known "deficits" in the area of SQL.

# re: Continued...

Friday, November 28, 2003 1:15 PM by Philip Rieck
They can also partition the data differently across disks. They can pin the correct tables in memory. They can do things I'm not aware of.

I've had a DBA team de-normalize tables and alter 13 sp's to reflect that - the app did not have to be recompiled (most of these were simple insert/select/delete that I did not think could be optimized. They could).

when you have an application with high performance requirements - even one with minor database requirements, a sql dba (A good one) can do a lot more than just set indicies.

You may not have worked with one - I know it's fairly rare - but I've seen miracles worked by setting obscure options in places that I didn't think could be optimized.

# Stored procedures vs. Ad-hoc queries

Thursday, December 18, 2003 8:25 AM by TrackBack

# re: Continued...

Saturday, January 03, 2004 9:31 AM by Les Miskin
I agree with Thomas Tomiczek's last post with regards to the business logic.

I'm developing a web application which manages dynamic tables which are created for customers. Because I'm not accessing a specific table, but rather a *type* of table with a variable title, SPROCS are completely useless to me because of the inability to operate with variable table names. This seems to be a great shame, as I can see how recompiling an application again just to change a simple query could become tiresome.

However, when executing an SPROC and returning a simple variable, the code required (for ADO) is far more complex and unnecessary compared to a far simpler dynamic SQL alternative.

# I like stored procs

Wednesday, February 18, 2004 8:24 AM by Tim Scarfe
Some general comments posted to blog @ http://www.developer-x.com/journal/2004/02/18/

# Evaluation of Stored Procedures for the .NET Developer

Tuesday, March 16, 2004 12:53 AM by TrackBack

# Evaluation of Stored Procedures for the .NET Developer

Tuesday, March 16, 2004 12:55 AM by TrackBack

# Stored Procs vs. Dynamic SQL

Sunday, September 05, 2004 9:30 AM by TrackBack

# Dynamic SQL vs Stored Procedures

Monday, September 06, 2004 11:10 AM by TrackBack