17.06.2013 Views

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 12: Stored Procedures<br />

400<br />

@ValueOut int OUTPUT<br />

AS<br />

DECLARE @InWorking int;<br />

DECLARE @OutWorking int;<br />

IF @ValueIn != 1<br />

BEGIN<br />

SELECT @InWorking = @ValueIn - 1;<br />

END<br />

ELSE<br />

BEGIN<br />

END<br />

RETURN;<br />

GO<br />

EXEC spFactorial @InWorking, @OutWorking OUTPUT;<br />

SELECT @ValueOut = @ValueIn * @OutWorking;<br />

SELECT @ValueOut = 1;<br />

So, what we’re doing is accepting a value in (that’s the value we want a factorial of) and providing a<br />

value back out (the factorial value we’ve computed). The surprising part is that our sproc does not, in<br />

one step, do everything it needs to calculate the factorial. Instead, it just takes one number’s worth of the<br />

factorial and then turns around and calls itself. The second call will deal with just one number’s worth<br />

and then again call itself. This can go on and on up to a limit of 32 levels of recursion. Once <strong>SQL</strong> <strong>Server</strong><br />

gets 32 levels deep, it will raise an error and end processing.<br />

Note that any calls into .NET assemblies count as an extra level in your recursion<br />

count, but anything you do within those assemblies does not count against the<br />

recursion limit. While .NET functionality in <strong>SQL</strong> <strong>Server</strong> is beyond the scope of this<br />

book, keep in mind that it is a potential way around nesting level issues.<br />

Let’s try out our recursive sproc with a little script:<br />

DECLARE @WorkingOut int;<br />

DECLARE @WorkingIn int;<br />

SELECT @WorkingIn = 5;<br />

EXEC spFactorial @WorkingIn, @WorkingOut OUTPUT;<br />

PRINT CAST(@WorkingIn AS varchar) + ‘ factorial is ‘ + CAST(@WorkingOut AS varchar);<br />

This gets us the expected result of 120:<br />

5 factorial is 120<br />

You can try different values for @WorkingIn and things should work just fine with two rather significant<br />

hitches:<br />

❑ Arithmetic overflow when our factorial grows too large for the int (or even bigint) data type<br />

❑ The 32-level recursion limit

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!