Presentation is loading. Please wait.

Presentation is loading. Please wait.

More on Procedures (Internal/Local procedures)

Similar presentations


Presentation on theme: "More on Procedures (Internal/Local procedures)"— Presentation transcript:

1 More on Procedures (Internal/Local procedures)
Please use speaker notes for additional information! This presentation includes information from the notes and additional examples. An internal or local procedure (there can be internal or local functions as well) is defined in the PL/SQL block in the DECLARE. Note that the PL/SQL block can be an anonymous block or a named block. Please contrast these examples with the examples of stored procedures discussed in the presentation Introduction to Procedures.

2 Internal/local Procedures
SQL> edit Call_Adddonproc1 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; 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; IF v_contamt > 20 THEN AddDonProc (v_idno, v_driveno, v_contamt); END IF; END; / SET VERIFY ON Note the location here! This is an internal procedure that has been embedded in the DECLARE portion of the PL/SQL block. The internal or local procedure must be the last thing in the DECLARE. When the call is made from the block BEGIN, the declared procedure is executed. Notice the way the execution works. The block BEGIN is executed. If the user entry stored in v_contamt is greater than 20, then the PROCEDURE is executed. When the procedure is complete control returns to the command after the call which ends the if and ends the anonymous block. Note that in the anonymous block I named the variables with a v in front of the name. These are the names that are passed to the internal procedure. They are stored in the procedure variables which have a p in front of the name. When the INSERT is done in the internal procedure, the names used are the names defined in the internal procedure.

3 Internal/local procedure
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; IF v_contamt > 20 THEN AddDonProc (v_idno, v_driveno, v_contamt); END IF; END; The internal procedure receives the data and inserts it into the new_donation table. Call_Adddonproc1 Enter value for input_idno: 12121 Enter value for input_driveno: 100 Enter value for input_contamt: 100 PL/SQL procedure successfully completed. SQL> SELECT * FROM new_donation; IDNO DRI CONTDATE CONTAMT JAN FEB MAR MAR MAR JUN JUN JUN JUN Processing starts. Since v_contamt is 100 the internal procedure is called and passed the input values. See the previous slide for the complete code in the anonymous block.

4 Internal/local procedure
SQL> edit Call_Adddonproc2 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; PROCEDURE AddDonProc (p_idno new_donation.idno%TYPE, p_driveno new_donation.driveno%TYPE, p_contamt new_donation.contamt%TYPE) AS BEGIN v_newcontamt := p_contamt * 1.1; INSERT INTO new_donation(idno, driveno, contamt) VALUES(p_idno, p_driveno, v_newcontamt); END AddDonProc; IF v_contamt > 20 THEN AddDonProc (v_idno, v_driveno, v_contamt); END IF; END; / SET VERIFY ON The calculation is being done in the procedure but it is using a variable defined in the main block. Data defined in the main block is available to an internal procedure.

5 Internal/local procedure
Call_Adddonproc2 Enter value for input_idno: 11111 Enter value for input_driveno: 100 Enter value for input_contamt: 120 PL/SQL procedure successfully completed. SQL> SELECT * FROM new_donation; IDNO DRI CONTDATE CONTAMT JAN FEB MAR MAR MAR JUN JUN JUN JUN 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; PROCEDURE AddDonProc (p_idno new_donation.idno%TYPE, p_driveno new_donation.driveno%TYPE, p_contamt new_donation.contamt%TYPE) AS BEGIN v_newcontamt := p_contamt * 1.1; INSERT INTO new_donation(idno, driveno, contamt) VALUES(p_idno, p_driveno, v_newcontamt); END AddDonProc; IF v_contamt > 20 THEN AddDonProc (v_idno, v_driveno, v_contamt); END IF; END; The three inputted values are passed to the internal procedure. One of them is used to calculate a new value that is stored in the external procedure. The output takes two of the passed value and the calculation stored in the output procedure and Inserts them into the table.

6 Internal/local procedure
SQL> edit Call_Adddonproc2a 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; PROCEDURE AddDonProc AS BEGIN v_newcontamt := v_contamt * 1.1; INSERT INTO new_donation(idno, driveno, contamt) VALUES(v_idno, v_driveno, v_newcontamt); END AddDonProc; IF v_contamt > 20 THEN AddDonProc; END IF; END; / SET VERIFY ON In fact, passing something to this subroutine was not necessary. You could have done the processing using the data in the anonymous block. Note that this example is not in the notes.

7 Internal/local procedure
Call_Adddonproc2a Enter value for input_idno: 33333 Enter value for input_driveno: 300 Enter value for input_contamt: 45 PL/SQL procedure successfully completed. Input truncated to 13 characters SQL> SELECT * FROM new_donation; IDNO DRI CONTDATE CONTAMT JAN FEB MAR MAR MAR JUN JUN JUN JUN 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; PROCEDURE AddDonProc AS BEGIN v_newcontamt := v_contamt * 1.1; INSERT INTO new_donation(idno, driveno, contamt) VALUES(v_idno, v_driveno, v_newcontamt); END AddDonProc; IF v_contamt > 20 THEN AddDonProc; END IF; END; Note some of the records are slightly different than in previous examples - tried too many things!. The last record added here is the one we are interested in. In this example nothing was passed to the internal procedure - it was simply called. It used the variable names defined within the declare to calculate a new contribution amount and write the idno, driveno and contribution amount to the table. Note the variety of other approaches covered in the notes.

8 Internal/local procedure
SQL> edit proc_dona1 DECLARE v_idno donation_unique.idno%TYPE :='&input_idno'; v_driveno donation_unique.driveno%TYPE; v_contamt donation_unique.contamt%TYPE; v_drivename drive.drivename%TYPE; PROCEDURE get_drive_name (p_driveno donation_unique.driveno%TYPE) AS BEGIN SELECT drivename into v_drivename FROM drive WHERE driveno = p_driveno; END get_drive_name; SELECT driveno, contamt INTO v_driveno, v_contamt FROM donation_unique WHERE idno = v_idno; get_drive_name(v_driveno); INSERT INTO donordrive(idno, driveno, contamt, drivename) VALUES(v_idno, v_driveno, v_contamt, v_drivename); END; / In the anonymous block, I have declared a group of variables and an internal or local named procedure. The processing starts with the block begin which selects a record according to user entered identification number. The drive number for that record is then passed to the procedure and within the procedure the drivename is retrieved. When the procedure is complete, processing returns to the main block and the information from the variables (including the retrieved drivename) is inserted in a new table.

9 Internal/local procedure
DECLARE v_idno donation_unique.idno%TYPE :='&input_idno'; v_driveno donation_unique.driveno%TYPE; v_contamt donation_unique.contamt%TYPE; v_drivename drive.drivename%TYPE; PROCEDURE get_drive_name (p_driveno donation_unique.driveno%TYPE) AS BEGIN SELECT drivename into v_drivename FROM drive WHERE driveno = p_driveno; END get_drive_name; SELECT driveno, contamt INTO v_driveno, v_contamt FROM donation_unique WHERE idno = v_idno; get_drive_name(v_driveno); INSERT INTO donordrive(idno, driveno, contamt, drivename) VALUES(v_idno, v_driveno, v_contamt, v_drivename); END; / Kids Shelter 100 10 10 proc_dona1 Enter value for input_idno: 22222 PL/SQL procedure successfully completed. SQL> SELECT * FROM donordrive; IDNO DRI CONTAMT DRIVENAME Kids Shelter The SELECT in the begin uses the user entered idno to select a record, putting information from the record into the variables. The call to get_drive_name passes the driveno The SELECT within the procedure gets the drivename from the drive file and stores it in the variables. When the procedure is complete control returns to the line after the call and the INSERT is executed which writes a record to the new file containing the information in the variables.

10 SQL> edit proc_dona2
Named procedure SQL> edit proc_dona2 DECLARE v_idno donation_unique.idno%TYPE :='&input_idno'; v_driveno donation_unique.driveno%TYPE; v_contamt donation_unique.contamt%TYPE; v_drivename drive.drivename%TYPE; BEGIN SELECT driveno, contamt INTO v_driveno, v_contamt FROM donation_unique WHERE idno = v_idno; named_get_drive_name(v_driveno, v_drivename); INSERT INTO donordrive(idno, driveno, contamt, drivename) VALUES(v_idno, v_driveno, v_contamt, v_drivename); END; / SQL> edit named_get_drive_name This anonymous block with a named procedure accomplishes the same thing that the anonymous block with the internal/local procedure on the previous slide accomplished. Note that I have defined an IN parameter to receive the driveno and an OUT parameter to return the drivename. Note that the call names both parameters. CREATE OR REPLACE PROCEDURE named_get_drive_name (p_driveno IN donation_unique.driveno%TYPE, p_drivename OUT drive.drivename%TYPE) AS BEGIN SELECT drivename into p_drivename FROM drive WHERE driveno = p_driveno; END; /

11 Named procedure named_get_drive_name Procedure created. SQL> edit proc_dona2 proc_dona2 Enter value for input_idno: 33333 PL/SQL procedure successfully completed. SQL> SELECT * FROM donordrive; IDNO DRI CONTAMT DRIVENAME Health Aid Kids Shelter Enter value for input_idno: 12121 Animal Home First, the named procedure must be created before the anonymous block that is calling it can be executed. As we saw on the previous slide, the user enters a number. The record is selected. Then the driveno is passed to the named procedure which retrieves the drivename and passes it to the anonymous block which then inserts the information into the table. Again please note that if you want records in a particular order in the table, use the order by clause. Hopefully these examples help to clarify the difference between a named procedure and an internal/local procedure.

12 Named procedure with cursor
DECLARE v_idno donation_unique.idno%TYPE; v_driveno donation_unique.driveno%TYPE; v_contamt donation_unique.contamt%TYPE; v_drivename drive.drivename%TYPE; CURSOR c_donor IS SELECT idno, driveno, contamt FROM donation_unique; BEGIN OPEN c_donor; FETCH c_donor INTO v_idno, v_driveno, v_contamt; WHILE c_donor%FOUND LOOP named_get_drive_name(v_driveno, v_drivename); INSERT INTO donordrive(idno, driveno, contamt, drivename) VALUES(v_idno, v_driveno, v_contamt, v_drivename); END LOOP; CLOSE c_donor; END; / SQL> edit proc_dona4 SQL> edit named_get_drive_name This slide uses a cursor to process all the records individually and write each one into a new table. Clearly individual processing based on IF statements etc. could be included. Note that the routine named_get_drive_name has not changed from the routine used in the previous slide. Note that as each record is processed, the procedure named-get_drive_name is called and the drive number is passed to it and the drive name is passed back. CREATE OR REPLACE PROCEDURE named_get_drive_name (p_driveno IN donation_unique.driveno%TYPE, p_drivename OUT drive.drivename%TYPE) AS BEGIN SELECT drivename into p_drivename FROM drive WHERE driveno = p_driveno; END; /

13 Named procedure with cursor
named_get_drive_name Procedure created. proc_dona4 PL/SQL procedure successfully completed. SQL> SELECT * FROM donordrive; IDNO DRI CONTAMT DRIVENAME Kids Shelter Animal Home Kids Shelter Health Aid Kids Shelter Again note that all records are processed.

14 Internal/local procedure with cursors
SQL> edit proc_dona3 DECLARE v_idno donation_unique.idno%TYPE; v_driveno donation_unique.driveno%TYPE; v_contamt donation_unique.contamt%TYPE; v_drivename drive.drivename%TYPE; CURSOR c_donor IS SELECT idno, driveno, contamt FROM donation_unique; PROCEDURE get_drive_name (p_driveno donation_unique.driveno%TYPE) AS BEGIN SELECT drivename into v_drivename FROM drive WHERE driveno = p_driveno; END get_drive_name; OPEN c_donor; FETCH c_donor INTO v_idno, v_driveno, v_contamt; WHILE c_donor%FOUND LOOP get_drive_name(v_driveno); INSERT INTO donordrive(idno, driveno, contamt, drivename) VALUES(v_idno, v_driveno, v_contamt, v_drivename); END LOOP; CLOSE c_donor; END; / This uses a cursor and an internal/local procedure to process the each record in the donation_unique file individually. The results are written to the donordrive.

15 Internal/local procedure with cursors
proc_dona3 PL/SQL procedure successfully completed. SQL> SELECT * FROM donordrive; IDNO DRI CONTAMT DRIVENAME Kids Shelter Animal Home Kids Shelter Health Aid Kids Shelter This is the output that is produced from the code on the previous slide. Note that because the procedure is internal it does not have to be created.


Download ppt "More on Procedures (Internal/Local procedures)"

Similar presentations


Ads by Google