Recursive Code without using SP

  • How to calculate a factorial of a number without using a stored procedure?

    Thanks in advance.....

  • Is function OK, then?


    N 56°04'39.16"
    E 12°55'05.25"

  • I don't get why recursive calls are so popular for factorial calculations...

    CREATE FUNCTION dbo.fnFactorial

    (

    @n BIGINT

    )

    RETURNS BIGINT

    AS

    BEGIN

    DECLARE @i BIGINT

    IF @n >= 0 AND @n <= 20

    SELECT @i = 1

    WHILE @n > 1

    SELECT @i = @i * @n,

    @n = @n - 1

    RETURN @i

    END


    N 56°04'39.16"
    E 12°55'05.25"

  • Thanks lot.... SQL script is possible?

    any ideas. Thanks..

  • Factorials are a perfect problem to use when teaching the concept of recursion. The solution is very simple and the definition is already stated in recursive form! ITRW, it is too simple -- so looping is used for better performance.

    If I understand the question, you want to use recursion without using a stored procedure or function -- just using an anonymous block of SQL script. Actually, it doesn't matter if you're asking about SQL or any other computer language, the answer is no. In order to use recursion, a block of code must reference itself. An anonymous block of code cannot be referenced. And if you try to use labels and GOTOs then you are just impersonating a loop.:P

    However, if you already have a recursive algorithm for solving your problem but you don't want to use recursion then, yes, you can convert any recursive algorithm into an ordinary looping structure.

    Tomm Carr
    --
    Version Normal Form -- http://groups.google.com/group/vrdbms

  • There is a solution without loops - single "select" (according to what "SQL" stands for).

    It involves very famous table Tally (regards to you know who ;))

    [Code]

    DECLARE @I BIGINT

    select @I = ISNULL(@I, 1) * N

    FROM dbo.Tally

    WHERE N > 0 AND N < = 5

    SELECT @I

    [/Code]

    _____________
    Code for TallyGenerator

  • Heh... this reminds me of doing volumetric rotations in Calc II... instructor was busting our chops about how he could do immensely accurate calcs to calculate the amount of material required to build some extremely complicated tri-axial objects in only about an hour using only a hand held calculator. He got pretty ticked when I told him I could do it in less than 30 seconds by just carefully submerging the object in a full bucket of water and measuring the water that spilled out of the bucket. 😛

    Same holds true here... you're only going to be able to get 20 factorial products into the likes of a BIGINT... why not calculate them just once and put them into a table? Then, the query would be...

    SELECT FactorialProduct

    FROM Factorial

    WHERE Factor = somenumber

    😉

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • But if capacity is more important for you than precision to the last digit then you probably will go with FLOAT result.

    For N = 115 it returns 2.9250936934930141E+188 and still takes no time.

    Limitation moves to N=170 with output = 7.257415615307994E+306

    _____________
    Code for TallyGenerator

  • True enough... and nicely done. I was being a bit sarcastic because the OP didn't want to use a stored procedure... I went a bit overboard with a way to do it in a single query with no declarations 😉

    Sometimes the requirements these poor folks get just amaze me... :hehe:

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Thanks lot for all people....

    But i got some idea from internet......

    -- Written by: Greg Larsen

    DECLARE @OUT BIGINT

    DECLARE @CMDX NVARCHAR(4000)

    DECLARE @Y INT

    -- set @Y to the number for which you want to find the factorial

    -- only works from 0 to 15 due to nesting level limit

    SET @Y=15

    -- declare the recursive command

    SET @CMDX = 'DECLARE @CMD NVARCHAR(4000) ' + CHAR(13) +

    'DECLARE @X BIGINT' + CHAR(13) +

    'SET @X = @Y' + CHAR(13) +

    'IF @Y = 0' + CHAR(13) +

    ' SELECT @OUT = 1' + CHAR(13) +

    'ELSE' + CHAR(13) +

    'BEGIN' + CHAR(13) +

    -- execute another time

    ' set @Y=@Y-1 ' + CHAR(13) +

    ' SET @CMD = @CMDX' + CHAR(13) +

    ' EXEC SP_EXECUTESQL @CMD,N''@Y INT,@CMDX NVARCHAR(1000),

    @OUT BIGINT OUT'',@Y=@Y,@cmdx=@cmdx,@OUT=@OUT OUT' + CHAR(13) +

    ' SELECT @OUT = @OUT * @X' + CHAR(13) +

    'END'

    -- Initialize the factorial value

    SET @OUT = 1

    -- execute the recursive call

    EXEC SP_EXECUTESQL @CMDX,N'@Y INT,@CMDX NVARCHAR(1000),

    @OUT BIGINT OUT',@Y=@Y,@CMDX=@CMDX,@OUT=@OUT OUT

    -- Print out the factorial answer

    PRINT 'The Factorial of ' + RTRIM(CAST(@Y AS CHAR)) +

    ' = ' + RTRIM(CAST(@OUT AS CHAR))

  • Jeff Moden (11/6/2007)


    True enough... and nicely done. I was being a bit sarcastic because the OP didn't want to use a stored procedure... I went a bit overboard with a way to do it in a single query with no declarations 😉

    Sometimes the requirements these poor folks get just amaze me... :hehe:

    You know, even 170 rows is not a big seal.

    🙂

    And you can never get "overflow" error. :w00t:

    _____________
    Code for TallyGenerator

  • Yes...Thank you very much...Recursion has some disadvantages. For Example:

    Each time we get one record from the DB, it takes n seconds.

    Each DB connection/disconnection takes n * 2 seconds.

    Allocating memory for a new incidence of the function takes n/10 * iteration seconds

    So, if we had 1000 messages in our discussion forum, the equation would look something like this:

    (1000 * n) + (1000 * n * 2) + (n/10 * iteration).

    In detail:

    Record 1: 3 * n seconds

    Record 250: 29 * n seconds

    Record 500: 53 * n seconds

    Record 750: 79 * n seconds

    Record 1000: 103 * n seconds

    ----------------------------

    Total = approx 50,000 * n seconds

    -----------------------------------

    Thanks,

    Kannan R

  • ??? Recursion has some disadvantages compared to what? And, I'm confused... tell me again why you would use a Factorial function in conjunction with forum messages :blink:

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Actually, I woluld like to display like heirarchical lists in my work.Because i used Recursion method.

    Thanks....

  • If you are going to use recursion a lot, then consider moving to SQL Server 2005. You can write recursive SQL using Common Table Experssions (CTEs), which is a lot simpler than the alternatives in SQL Server 2000.

    (Unless of course you can exploit Jeff's idea of storing per-prepared results in a table...)

    Example of recursive SQL from the SQL 2005 BOL...

    USE AdventureWorks;

    GO

    WITH DirectReports(ManagerID, EmployeeID, EmployeeLevel) AS

    (

    SELECT ManagerID, EmployeeID, 0 AS EmployeeLevel

    FROM HumanResources.Employee

    WHERE ManagerID IS NULL

    UNION ALL

    SELECT e.ManagerID, e.EmployeeID, EmployeeLevel + 1

    FROM HumanResources.Employee e

    INNER JOIN DirectReports d

    ON e.ManagerID = d.EmployeeID

    )

    SELECT ManagerID, EmployeeID, EmployeeLevel

    FROM DirectReports ;

    GO

    Original author: https://github.com/SQL-FineBuild/Common/wiki/ 1-click install and best practice configuration of SQL Server 2019, 2017 2016, 2014, 2012, 2008 R2, 2008 and 2005.

    When I give food to the poor they call me a saint. When I ask why they are poor they call me a communist - Archbishop Hélder Câmara

Viewing 15 posts - 1 through 15 (of 19 total)

You must be logged in to reply to this topic. Login to reply