SQL Proc factorial
SQL
Download (.zip)
use pubs go
SET NOCOUNT ON go
if exists (select * from sysobjects where name='factorial' and type='P') DROP PROC factorial go
-- SQL Server supports recursion !! -- Recursively calculate factorial of numbers between 0 and 12 -- Parameters greater than 12 are disallowed as result overflows the bounds of an int
CREATE PROC factorial @param1 int as declare @one_less int, @answer int IF (@param1 < 0 OR @param1 > 12) BEGIN -- Illegal Parameter Value . Must be between 0 and 12 RETURN -1 END
IF (@param1 = 0 or @param1 = 1) select @answer=1 else BEGIN SELECT @one_less=@param1 - 1 exec @answer=factorial @one_less -- RECURSIVELY CALL ITSELF IF (@answer= -1) BEGIN RETURN -1 END
SELECT @answer=@answer * @param1 IF (@@error <> 0) RETURN -1 END
RETURN(@answer) go
declare @answer numeric,@param int select @param=0 WHILE (@param <= 12) BEGIN exec @answer=factorial @param IF (@answer = -1) BEGIN RAISERROR('Error executing factorial procedure.',16,-1) RETURN END select convert(varchar,@param) + '! = ' + convert(varchar,@answer) select @param=@param + 1 END
-- Alternative solution uses an output parameter to return a value of -- type decimal (38,0)
if exists (select * from sysobjects where name='factorial2' and type='P') DROP PROC factorial go
CREATE PROC factorial @param1 decimal(38,0), @answer decimal(38,0) output AS DECLARE @one_less decimal(38,0), @status int
IF (@param1 < 0 OR @param1 > 32) BEGIN -- Illegal parameter value. Must be between 0 and 12. RETURN -1 END
IF (@param1=0 or @param1=1) SET @answer=1 ELSE BEGIN SET @one_less=@param1 - 1 EXEC @status=factorial @one_less, @answer output -- Recursively call itself IF (@status= -1) BEGIN RETURN -1 END
SET @answer=@answer * @param1
IF (@@ERROR <> 0) RETURN -1 END
RETURN 0
-- Alternative iterative solution does not have the restriction of 32 -- nesting levels.
if exists (select * from sysobjects where name='factorial2' and type='P') DROP PROC factorial2 go
CREATE PROC factorial2 @param1 int, @answer numeric(38,0) output as declare @counter int IF (@param1 < 0 OR @param1 > 34) BEGIN RAISERROR ('Illegal Parameter Value . Must be between 0 and 34',16,-1) RETURN -1 END
SELECT @counter= 1, @answer=1
WHILE (@counter < @param1 AND @param1 <> 0 ) BEGIN SET @answer=@answer * (@counter + 1) SET @counter=@counter+1 END RETURN go
declare @answer numeric(38,0),@param int select @param=0 WHILE (@param <= 34) BEGIN exec factorial2 @param, @answer output select convert(varchar(50),@param) + '! = ' + convert(varchar(50),@answer) select @param=@param + 1 END
|