<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Peter DeBetta's SQL Programming Blog : Ad-hoc</title><link>http://sqlblog.com/blogs/peter_debetta/archive/tags/Ad-hoc/default.aspx</link><description>Tags: Ad-hoc</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Yet Another Stored Procedure vs. Ad-hoc Query Discussion?</title><link>http://sqlblog.com/blogs/peter_debetta/archive/2008/04/03/yet-another-stored-procedure-vs-ad-hoc-query-discussion.aspx</link><pubDate>Thu, 03 Apr 2008 04:44:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6009</guid><dc:creator>Peter W. DeBetta</dc:creator><slash:comments>9</slash:comments><comments>http://sqlblog.com/blogs/peter_debetta/comments/6009.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/peter_debetta/commentrss.aspx?PostID=6009</wfw:commentRss><description>&lt;P&gt;Earlier today, Will Sullivan posted a blog entry, &lt;A href="http://statestreetgang.net/post/2008/04/My-Statement-on-Stored-Procedures.aspx"&gt;My Statement on Stored Procedures&lt;/A&gt;, in which he emphatically states his official opinion of stored procedures as:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;"I prefer not to use them."&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;He then goes about dismissing most of the misinformation about why stored procedures are better than ad-hoc (parameterized) queries.&lt;/P&gt;
&lt;P&gt;The first bit of misinformation he dispels is the now defunct argument that "&lt;EM&gt;Stored Procedures are faster than ad-hoc queries&lt;/EM&gt;". He states that "Unless your ad-hoc queries are always significantly different from each other, their execution plans are cached right along side those of the SP's." I completely agree. We'll call that one a tie, so the score so far: &lt;STRONG&gt;SP 0, Ad-hoc 0.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Another myth he tries to debunk is that "&lt;EM&gt;Editing SP's is a breeze with Query Analyzer&lt;/EM&gt;". Query Analyzer - that's so SQL Server 2000. Seriously, though, there are a number of fine code editors that allow you to edit SPs with ease. Query Analyzer is not at the top of that list, however. I will say that when you write T-SQL you should use a code editor that is meant for T-SQL, for the same reasons that when you write C#, you want to use a code editor meant for C#. Again, no winner here, so the score remains: &lt;STRONG&gt;SP 0, Ad-hoc 0.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;He addresses another statement that is supposedly made in defense of SPs: "&lt;EM&gt;Ad-hoc queries are a nightmare to maintain, as they are spread all over your code&lt;/EM&gt;". Again, either one is easy to maintain, with the right tools. We are still scoreless: &lt;STRONG&gt;SP 0, Ad-hoc 0.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;It just so happens that I agree with many of his points. And there are other objective and subjective points on topics such as organization, maintenance, design, and so on, which one could argue for either SPs or ad-hoc queries equally so. &lt;STRONG&gt;Don't get me wrong, however, as I believe that using ad-hoc queries when you could have used stored procedures is simply wrong.&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;And so I will address Will's last point (actually, it was his second point) that is repeatedly misrepresented: "&lt;EM&gt;Stored Procedures are safe against SQL injection attacks; ad-hoc queries are not&lt;/EM&gt;".&lt;/P&gt;
&lt;P&gt;Ad-hoc queries prevent SQL Injection attacks as well as SPs do. Any claim otherwise would be wrong. But that's not the issue. The problem is that ad-hoc queries require that you expose the underlying objects of the database. In order to use ad-hoc queries, you must allow direct access for select, insert, update, and delete operations to the tables in the database. Although I know most experienced developers would only write ad-hoc/parameterized queries against the underlying data, at a later date, some disgruntled or inexperienced developer may write dynamic SQL instead (I have seen it happen), and expose the database to SQL injection attacks (which I have also seen in production systems), including exposure to such awful actions as...&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:green;"&gt;--&amp;nbsp;Can&amp;nbsp;you&amp;nbsp;say&amp;nbsp;Identity&amp;nbsp;Theft? &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;FirstName&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;LastName&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;ZIP&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;CreditCardNumber&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;CreditCardType&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;CreditCardExpoiration&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:black;"&gt;CVV&amp;nbsp; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;FROM&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR:black;"&gt;&lt;FONT face="Courier New"&gt;Customers &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;...or worse...&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:green;"&gt;--&amp;nbsp;Do&amp;nbsp;we&amp;nbsp;really&amp;nbsp;need&amp;nbsp;all&amp;nbsp;those&amp;nbsp;customers? &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;DELETE&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;Customers &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;...or even worse...&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:green;"&gt;--&amp;nbsp;NEVER&amp;nbsp;EVER&amp;nbsp;DO&amp;nbsp;THIS,&amp;nbsp;PLEASE &lt;BR&gt;--&amp;nbsp;This&amp;nbsp;will&amp;nbsp;execute&amp;nbsp;a&amp;nbsp;DELETE&amp;nbsp;against&amp;nbsp;all&amp;nbsp;tables &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;EXEC&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:darkred;"&gt;sp_MSforeachtable&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;'DELETE&amp;nbsp;?'&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;...or even, even worse (assuming the SQL login has elevated permissions - which many apps do)...&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:green;"&gt;--&amp;nbsp;NEVER&amp;nbsp;EVER&amp;nbsp;DO&amp;nbsp;THIS,&amp;nbsp;PLEASE &lt;BR&gt;--&amp;nbsp;This&amp;nbsp;will&amp;nbsp;drop&amp;nbsp;all&amp;nbsp;tables&amp;nbsp;from&amp;nbsp;the&amp;nbsp;database &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;EXEC&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:darkred;"&gt;sp_MSforeachtable&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;'DROP&amp;nbsp;TABLE&amp;nbsp;?'&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;...and so although your ad-hoc query code won't allow SQL injection, some other programmer's dynamic SQL will. Assuming you've correctly secured your database, this doesn't happen with stored procedures since you do not have to expose any of the underlying tables (because of a little something known as chain of ownership).&lt;/P&gt;
&lt;P&gt;Of course, you could completely self-destruct any security benefits by creating a SP such as this one:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:green;"&gt;--&amp;nbsp;NEVER&amp;nbsp;EVER&amp;nbsp;DO&amp;nbsp;THIS,&amp;nbsp;PLEASE,&amp;nbsp;I&amp;nbsp;beg&amp;nbsp;of&amp;nbsp;you... &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;CREATE&amp;nbsp;PROC&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;prExecuteSql&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:#434343;"&gt;@sql&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;VARCHAR&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;MAX&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:gray;"&gt;)) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;WITH&amp;nbsp;EXECUTE&amp;nbsp;AS&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR:black;"&gt;&lt;FONT face="Courier New"&gt;dbo &lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:blue;"&gt;AS&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:#434343;"&gt;@sql&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR:gray;"&gt;) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;GO&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;As you can see, SPs aren't fool proof, but you can mitigate your risk by having an employee or a consultant who knows what they are doing in the database. &lt;/P&gt;
&lt;P&gt;Yes, there are some applications will not require the extra security, or other factors may simply prevent you from using stored procedures, and so using ad-hoc SQL is a viable option in those cases. But I believe that security should be at the top of your important-things-for-your-application list, and&amp;nbsp;alas, ad-hoc queries require you to unnecessarily expose your database objects, which will more than likely lead to problems down the road.&amp;nbsp; You can argue any other point and there are no clear winners, but when it comes to security, ad-hoc loses. If you want to a more secure database, you need to be using SPs. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;And so, the final score (well, for now anyways): SP 1, Ad-hoc 0. &lt;/STRONG&gt;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=6009" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/peter_debetta/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://sqlblog.com/blogs/peter_debetta/archive/tags/Code/default.aspx">Code</category><category domain="http://sqlblog.com/blogs/peter_debetta/archive/tags/Ad-hoc/default.aspx">Ad-hoc</category><category domain="http://sqlblog.com/blogs/peter_debetta/archive/tags/Stored+Procedures/default.aspx">Stored Procedures</category></item></channel></rss>