views:

156

answers:

1

This is going to be both a direct question and a discussion point. I'll ask the direct question first:

Can a stored procedure create another stored procedure dynamically? (Personally I'm interested in SQL Server 2008, but in the interests of wider discussion will leave it open)

Now to the reason I'm asking. Briefly (you can read more elsewhere), User Defined Scalar Functions in SQL Server are performance bottlenecks, at best. I've seen uses in our code base that slow the total query down by 3-4x, but from what I've read the local impact of the S-UDF can be 10x+

However, UDFs are, potentially, great for raising abstraction levels, reducing lots of tedious boilerplate, centralising logic rules etc. In most cases they boil down to simple expressions that could easily be expanded inline - but they're not (I'm really only thinking of non-querying functions - e.g. string manipluations). I've seen a bug report for this to be addressed in a future release - with some buy-in from MS. But for now we have to live with the (IMHO) broken implementation.

One workaround is to use a table value UDF instead - however these complicate the client code in ways you don't always want to deal with (esp. when the UDF just computes the result of an expression).

So my crazy idea, at first, was to write the procs with C Preprocessor directives, then pass it through a preprocessor before submitting to the RDBMS. This could work, but has its own problems.

That led me to my next crazy idea, which was to define the "macros" in the DB itself, and have a master proc that accepts a string containing an unprocessed SP with macros, expands the macros inline, then submits it on to the RDMS. This is not what SPs are good at, but I think it could work - assuming you can do this in the first place - hence my original question.

However, now I have explained my path to the question, I'd also like to leave it open for other ideas. I'm sure I'm not the only one who has been thinking along these lines. Perhaps there are third-party solutions already out there? My googling has not turned up much yet. Also I thought it would be a fun discussion topic.

[edit]

This blog post I found in my research describes the same issue I'm seeing. I'd be happy if anyone could point out something that I, or the blog poster, might be doing wrong that leads to the overhead.

I should also add that I am using WITH SCHEMABINDING on my S-UDF, although it doesn't seem to be giving me any advantage

A: 

your string processing UDF won't be a perf problem. Scalar UDF's are a problem only when they perform selects and those selects are done for every row. this in turn spikes the IO. string manipulaation on the other hand is done in memory and is fast.

as for your idea i can't really see any benefit of it. creating and dropping objects like that can be an expensive operation and may lead to schema locking.

Mladen Prajdic
The UDF I have in my case is doing just a few string manipulations and is used on a couple of fields returned from a select statement. I see the 3-4x slow down compared to hand coding the same manipluations directly into the select.A bit of research led me to a few blog posts such as this one: http://thehobt.blogspot.com/2009/02/scalar-functions-vs-table-valued.html - which bear out the high overhead (and led me to 10x figure). Note that in that article the UDF is doing just an LTRIM(RTRIM()).I'd be very happy if I was shown to be doing something wrong and the overhead could go away
Phil Nash
also, as I said to astander too, I'm only proposing the dynamic expansion of the stored proc be done on submission.
Phil Nash