More on Procedures and Functions
Remember, I am only INTRODUCING FUNCTIONS AND PROCEDURES in this course because we seem to
have some extra time. You really need to do extensive reading on this topic because there
are a lot of effective ways of approaching them and a lot of constraints that you need to
make yourself aware of.
We are now going to look at a PL/SQL block of code that has both an internal procedure and
an internal function. In the main block, I am looking at an input contribution amount.
Depending on the amount, I set a code that will be passed to the function. The function
uses the code to calculate the new contribution amount - my this is what you should give
therefore what you did give - and passes it back to the main block which now calls the
procedure to insert the new amounts in the new_donation table. In many ways this is
adding extra work that would not be there if I had eliminate functions and procedures, but
simple examples frequently have redundancy in them.
Looking at the code. The function is receiving the v_code and the v_amount that are passed
and is storing them as f_code and f_contamt. Remember the pass for the function is
accomplished with the statement: v_newcontamt := CalcNewDon(v_code, v_contamt); where
CalcNewDon is the name of the function and the values in v_code and v_contamt are being
passed to it. Note that v_newcontamt will received the result that is returned after the
function has been executed. The statement: RETURN f_newcontamt; is the statement that
sends back what is in f_newcontamt and it will be assigned to v_newcontamt.
There is one significant rule that we need to be aware of. When I described f_code and
f_contamt, I gave them a type and not a length. The constraint of a length is not allowed
in this definition area within a function. I did try using TYPE here, for example giving
f_code a type of v_code and that worked. If you want more information on this, it is
available in the PL/SQL book that was suggested for the course or you can look for notes
up functions and parameters on the Internet.
Note that in the function, I passed the amount to it as well as the code. The processing
would have worked if I had simply passed the code and used v_contamt instead of f_contamt
in the processing. However, it is a good idea to pass the function the things that it
needs and have it basically self-sufficient.
The procedure is the same as that in previous examples. The statement:
AddDonProc (v_idno, v_driveno, v_newcontamt); sends the three pieces of data to the
procedure where they are stored as p_idno, p_driveno and p_contamt. They are then used
in the INSERT to write a new record/row to the new_donation table.
SQL CODE:
SQL> edit call_adddonproc6
PL/SQL CODE:
SET VERIFY OFF
DECLARE
v_idno new_donation.idno%TYPE :='&input_idno';
v_driveno new_donation.driveno%TYPE :='&input_driveno';
v_contamt new_donation.contamt%TYPE :=&input_contamt;
v_newcontamt new_donation.contamt%TYPE;
v_code VARCHAR2(2);
FUNCTION CalcNewDon
(f_code VARCHAR2, f_contamt NUMBER)
RETURN NUMBER IS
f_newcontamt new_donation.contamt%TYPE;
BEGIN
IF f_code = 'EX' THEN
f_newcontamt := f_contamt * 1.3;
ELSE
IF f_code = 'VG' THEN
f_newcontamt := f_contamt * 1.2;
ELSE
IF f_code = 'OK' THEN
f_newcontamt := f_contamt * 1.1;
ELSE
f_newcontamt := f_contamt;
END IF;
END IF;
END IF;
RETURN f_newcontamt;
END CalcNewDon;
PROCEDURE AddDonProc
(p_idno new_donation.idno%TYPE,
p_driveno new_donation.driveno%TYPE,
p_contamt new_donation.contamt%TYPE) AS
BEGIN
INSERT INTO new_donation(idno, driveno, contamt)
VALUES(p_idno, p_driveno, p_contamt);
END AddDonProc;
BEGIN
IF v_contamt > 500 THEN
v_code := 'EX';
v_newcontamt := CalcNewDon(v_code, v_contamt);
ELSE
IF v_contamt > 250 THEN
v_code := 'VG';
v_newcontamt := CalcNewDon(v_code, v_contamt);
ELSE
IF v_contamt > 100 THEN
v_code := 'OK';
v_newcontamt := CalcNewDon(v_code, v_contamt);
ELSE
v_code := 'NG';
v_newcontamt := CalcNewDon(v_code, v_contamt);
END IF;
END IF;
END IF;
AddDonProc (v_idno, v_driveno, v_newcontamt);
END;
/
SET VERIFY ON
SQL CODE:
SQL> @ call_adddonproc6
Enter value for input_idno: 11111
Enter value for input_driveno: 100
Enter value for input_contamt: 700
PL/SQL procedure successfully completed.
Input truncated to 13 characters
SQL> SELECT * FROM new_donation;
IDNO DRI CONTDATE CONTAMT
----- --- --------- ---------
11111 100 07-JAN-99 25
12121 200 23-FEB-99 40
23456 100 03-MAR-99 20
33333 300 10-MAR-99 10
22222 100 14-MAR-99 10
12121 100 04-JUN-99 50
11111 200 12-JUN-99 35
23456 300 14-JUN-99 10
12121 300 10-JUN-99 75
12121 100 100
11111 100 910
11 rows selected.
SQL> @ call_adddonproc6
Enter value for input_idno: 22222
Enter value for input_driveno: 200
Enter value for input_contamt: 300
PL/SQL procedure successfully completed.
Input truncated to 13 characters
SQL> SELECT * FROM new_donation;
IDNO DRI CONTDATE CONTAMT
----- --- --------- ---------
11111 100 07-JAN-99 25
12121 200 23-FEB-99 40
23456 100 03-MAR-99 20
33333 300 10-MAR-99 10
22222 100 14-MAR-99 10
12121 100 04-JUN-99 50
11111 200 12-JUN-99 35
23456 300 14-JUN-99 10
12121 300 10-JUN-99 75
12121 100 100
11111 100 910
22222 200 360
12 rows selected.