I'm aware that this is a very heated debate, I'm also aware that however I form this post there will always be opinions that are opposite from mine. But never the less I would like to write a little about why I put stored procedures on the substitutions bench and only call them in where something can't be solved in any other way.
To be clear; My position is not that stored procedures are "evil" or have no use at all, my position is that stored procedures usually forces me to abstain other technologies and techniques I value more. Furthermore, there are will always be scenarios where stored procedures is the preferred solution, I just don't believe in making them my default choice.
So let's get to it, first my main pain points:
Pain point #1: Stored Procedures lack proper version management
Sprocs don't version easily. There are a lot of challenges with version management and sprocs the database can only have exactly one version of the sproc at any given time. If I want to support two versions I need two separate sprocs. This might seem trivial but when you build multi-tenant systems where versions aren't just about bug fixes and new features, but slight nuances in the way they should behave for different tenants (customer Acme's business differs from customer Mechanics business), it becomes a bit more messy.
Additionally, for a long long time there hasn't been a good source control story around sprocs. That have change now with the new database role in Visual Studio 2008 Team System and the database project type (which rocks btw). Even though I like the database role I still feel that the story around code versions and version control isn't strong enough and therefor pains me.
Pain point #2: Stored procedures forces me to maintain two code bases
Having code in the database forces me to maintain two different code bases and maintain two different skill sets. It also moves me out of my environment with the tools I'm used to have like ReSharper, a proper debugging environment and all the other nice things I use when writing C# code. Maintaining two code bases also makes me less flexible, less agile if you will, and I just don't like it.
Pain point #3: T-SQL Doesn't express business logic well
I can't say I'm an expert on T-SQL, but I'm fairly good at it. My view on T-SQL is that it's really good at querying but for expressing business logic it lacks a lot of constructs that I get from a good solid OO language. I can't use well known patterns like the strategy pattern to vary calculations or other parts of the business logic, it's much harder to take other factors then pure data from the database in account when working out the logic. And frankly it is ugly and have very poor readability. Which in terms means that it will be much harder to maintain.
Pain point #4: Stored procedures are hard to test
It's impossible to test sprocs in isolation. It's also impossible to test sprocs without firing up a database. Testing with a database takes a lot of time and a lot of effort. Microsoft has, again, improved this area a bit with their Database role in Visual Studio 2008, but it's not really enough for me. My testing requirements go past the functionality I get from Visual Studio. Sure, for testing database interaction it works like a charm but for proper unit testing it just doesn't cut it. Also since sprocs often look like transaction scripts, they are usually these big things and it's very hard to test parts of the sproc in isolation, you have to test everything or nothing.
Pain point #5: Stored procedures forces me to write T-SQL for trivial tasks
Why should I have to write trivial T-SQL queries myself when I can have a tool do it for me? No doubt that if I'm really, really good at writing queries for my scenario and stick them into a sproc that I might get a little better performance then something auto-generated and generic. But is it worth the time you have to put in? I don't think it is. If I got a serious performance problem I will address it when it arises, not before. Premature optimization being the root to all evil and all that. I really believe that the gain I get in productivity is worth the loss in performance (if any; putting a query in a sproc doesn't guarantee better performance). It might even be that the tool generates better queries then those that I can write myself (and that probably goes for some of your queries as well ;)
Edit @ 16:13, forgot one :)
Pain point #6: Stored procedures are static
Stored procedures are not flexible around parameters and for every variation of parameters, joins, orders or other differences I might want; I need a separate sproc to support it. This means that if I want a query that is slightly different I need to copy and paste the sproc, change what differs and now maintain two similar sprocs, remember to change them both. Again, maintenance suffers.
So what do I suggest instead?
My last pain point kind of reveals where I'm going with this. I prefer dynamic SQL generated by a tool. I prefer it because it lacks the above pain points and makes me much more productive.
That's why my default architecture always starts out with an ORM and dynamic SQL if I need to talk to a database, it will generate all the trivial SQL, it will enable me to test in isolation, there will only be one code base to maintain, versioning works a lot better and all my favorite tools will help me write good and solid code.
Does that mean I don't use sprocs at all? Certainly not, but dynamic SQL is my default and I call sprocs in when I think I need them, which these days are very very rare.
The coming weeks I'll try to explain some of the misunderstandings around dynamic SQL in comparison to sprocs and also talk a little bit on particular solutions and how I go about them.
--
More information on ...
... visual studio team system database role: http://msdn.microsoft.com/en-us/vsts2008/products/bb933747.aspx
... ReSharper: http://www.jetbrains.com
... Object Relational Mapping: http://en.wikipedia.org/wiki/Object-relational_mapping
... Transaction Script: http://www.martinfowler.com/eaaCatalog/transactionScript.html