Home > Net >  PL/SQL CREATE PROCEDURE - factorial
PL/SQL CREATE PROCEDURE - factorial

Time:12-01

I don't know what's wrong with my code block to create a procedure to find out the factorial of a number. Thank you.

-- Question 1 – Write a store procedure that gets an integer number n and --calculates and displays its factorial.

SET SERVEROUTPUT ON;

CREATE OR REPLACE PROCEDURE factorial_number(
    n NUMBER) AS
    factorial NUMBER;
    num Number;
BEGIN
    FOR i IN REVERSE 1..n LOOP
    num := i - 1;
    factorial := factorial * num;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE (factorial);
EXCEPTION
    WHEN OTHERS
    THEN  DBMS_OUTPUT.PUT_LINE ('Error!');
END;
/
BEGIN
    factorial_number(5);
END;
/

CodePudding user response:

How about

SQL> CREATE OR REPLACE PROCEDURE factorial_number (n NUMBER)
  2  AS
  3     factorial  NUMBER := 1;
  4  BEGIN
  5     FOR i IN 1 .. n
  6     LOOP
  7        factorial := factorial * i;
  8     END LOOP;
  9
 10     DBMS_OUTPUT.PUT_LINE (factorial);
 11  END;
 12  /

Procedure created.

SQL>


SQL> BEGIN
  2     factorial_number (5);
  3  END;
  4  /
120

PL/SQL procedure successfully completed.

SQL>

CodePudding user response:

  1. You're failing to initialize the local variable factorial. Uninitialized variables are initially null and multiplying null by any value produces null.
  2. I don't see why you'd want your loop to go in reverse order. It doesn't matter since multiplication is communitive but it it unlikely to make your code easier to read/ debug/ follow.
  3. You don't want to subtract 1 from the value you are multiplying by on each iteration of the loop. When i = 1, for example, you're multiplying factorial by 0 which means that (assuming you initialize factorial), you'd always end up with 0. You want to multiply by i so there is no need for the local variable num.

If I make those fixes

CREATE OR REPLACE PROCEDURE factorial_number(
    n NUMBER) 
AS
    factorial NUMBER := 1;  -- Initialize
BEGIN
    FOR i IN 1..n LOOP -- Loop normally
      dbms_output.put_line( 'Beginning iteration ' || i || ' of loop. ' ||
                            'Factorial = ' || factorial ||
                            ' multiplying by ' || i );
      factorial := factorial * i; -- Multiply by i not i-1
    END LOOP;
    DBMS_OUTPUT.PUT_LINE (factorial);
EXCEPTION
    WHEN OTHERS
    THEN  DBMS_OUTPUT.PUT_LINE ('Error!');
END;

Then

BEGIN
    factorial_number(5);
END;

will print out 120 (5*4*3*2*1).

I'm also adding an additional dbms_output line to print out the current state of the variables on each iteration of the loop. That's a relatively old-school method of debugging. In the modern world, you'd walk through the code with a debugger where you can see the values of your local variables but introductory classes may not teach debugger usage initially.

  • Related