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

Karl Seguin

.NET From Ottawa, Ontario

Minimizing duplication in sprocs

Not too long ago, I was experimenting with ways to minimize some code duplication in sprocs. Specifically, I wanted to figure out a way to centralize the SELECT X, Y, Z parts of my stored procedures.

For example, I had the following three sprocs:

  • GetAllArticles
  • GetArticleById
  • GetArticlesFromTags

I wrote GetAllArticles first, and it was a basic sproc:

 SELECT ArticlelId, Description, DateSubmitted, Status
        FROM Articles

 
Eventually, I wrote GetArticleById:

  SELECT ArticlelId, Description, DateSubmitted, Status
        FROM Articles
        WHERE ArticleId = @ArticleId

 
Humm...I'd done this a thousand times before...and like always, something didn't seem right. These selects are mapped (straightforwardly and manually) to an Article object. The problem comes if I add/remove a property. I change my 1 class definition and my 1 mapping, but I need to change each and every sproc where I pull an "Article", which might be a lot.

My solution was to let my Stored Procedures get the primary keys, store them (maybe in a temp table?) and call on another sproc to select the actual columns. something like (I'm doing this from the top of my head, since this isn't the actual approach I took):

 
--GetAllArticles:

DECLARE #temp (id INT)
INSERT INTO #temp
    SELECT ArticleId from Articles

EXEC GetAritlcesFromTempTable
DROP TABLE #temp


--GetArticleById:

CREATE TABLE #temp (id INT)

INSERT INTO #temp
  SELECT @ArticleId

EXEC GetAritlcesFromTempTable
DROP TABLE #temp

 

--GetAritlcesFromTempTable

SELECT ArticlelId, Description, DateSubmitted, Status
     FROM Articles WHERE ArticleId IN (SELECT id FROM #temp)

 

Now, truth be told, I was playing with SQL Server 2005's XML capabilities at the time, so I went the XML route instead of the temp table route, but you get the idea.  I never did get to play with it much, but I always thought the approach had some value.

 

updated: with some corrections provided by Jorn (3rd comment)


Published Sep 06 2006, 08:53 AM by karl
Filed under:

Comments

Travis Laborde said:

I've used views for this.  Since you want the same columns in each case, and only the logic of which rows you want will change, have a view which defines the columsns, the joins, etc.

Then the sprocs can be like this:

select * from vwArticles

or

select * from vwArticles where ID = 5

etc.

# September 6, 2006 11:46 AM

karl said:

but of course!

# September 6, 2006 11:58 AM

Jørn Aakre said:

A view will not work in all scenarios. For example:

-- GetArticlesThatUserHasBought

CREATE TABLE #temp (id INT)

INSERT INTO #temp

  SELECT DISTINCT ArticleId FROM OrderDetails WHERE UserID = @UserID

EXEC GetAritlcesFromTempTable

But a dedicated sp or view would probably be faster...

Any facts(/thoughts) about performance for your sp solution?

Some syntax corrections to your examples:

--GetAritlcesFromTempTable

SELECT ArticlelId, Description, DateSubmitted, Status

    FROM Articles WHERE ArticleID IN (SELECT id FROM #temp)

--GetArticleById:

CREATE TABLE #temp (id INT)

INSERT INTO #temp

  SELECT @ArticleId

EXEC GetAritlcesFromTempTable

DROP TABLE #temp

# September 6, 2006 12:31 PM

karl said:

Thanks for the corrections Jørn, I've updated the code samples.

I don't have any facts about performance, but I do think worrying about it for most apps would be a premature micro optimization. The nice thing about it is that you dont' have to use it for all sprocs. If you need to optimize one, then just do it the normal way. If the Articles table was huge it could be a problem because what you'd normally do in 1 select is now being done in 2.

# September 6, 2006 5:25 PM

Mischa Kroon said:

I would have to say who cares about duplication, you don't want to be doing these things by hand anyways.

Generating these stored procedures can be automated by a number of code generating utilities.

Also the performance of what you suggest should be less then optimal.

# September 14, 2006 5:23 AM

karl said:

Mischa:

The goal isn't so much the duplication in writing them, it's more about maintenance. Code generators are great at spitting out code to get you started, but they lack in their ability to help you refine here and modify there.

# September 14, 2006 6:45 AM

Mischa Kroon said:

True, but why mess with the basic procedures when you can just regenerate.

When you want to customize then there are also ways for this with blocks to leave alone. ( most code generators support this )

Or use seperate SP's using it's descriptive name to announce that it does something different then a select *.

You might want to look at table variables instead of temp tables which are said to perform a bit better.

http://databases.aspfaq.com/database/should-i-use-a-temp-table-or-a-table-variable.html

# September 14, 2006 7:17 AM

Leave a Comment

(required)  
(optional)
(required)  

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

Our Sponsors

Free Tech Publications