16.1.1 Get Stored Code Information from the Data Dictionary Answer the following questions: a) | Query the data dictionary to determine all the stored procedures, functions, and packages in the current schema of the database. Also include the current status of the stored code. Write the SELECT statement. | b) | Type the following script into a text file and run the script in SQL*Plus. It creates the function scode_at_line . Explain what the purpose of this function is. What is accomplished by running it? When does a developer find it useful? | FOR EXAMPLE -- ch16_1a.sql CREATE OR REPLACE FUNCTION scode_at_line (i_name_in IN VARCHAR2, i_line_in IN INTEGER := 1, i_type_in IN VARCHAR2 := NULL) RETURN VARCHAR2 IS CURSOR scode_cur IS SELECT text FROM user_source WHERE name = UPPER (i_name_in) AND (type = UPPER (i_type_in) OR i_type_in IS NULL) AND line = i_line_in; scode_rec scode_cur%ROWTYPE; BEGIN OPEN scode_cur; FETCH scode_cur INTO scode_rec; IF scode_cur%NOTFOUND THEN CLOSE scode_cur; RETURN NULL; ELSE CLOSE scode_cur; RETURN scode_rec.text; END IF; END; c) | Type DESC USER_ERRORS. What do you see? In what way do you think this view is useful for you? | d) | Type the following script to force an error. CREATE OR REPLACE PROCEDURE FORCE_ERROR as BEGIN SELECT course_no INTO v_temp FROM course; END; Now type: SHO ERR What do you see? | e) | How can you retrieve information from the USER_ERRORS view? | f) | Type DESC USER_DEPENDENCIES. What do you see? How can you make use of this view? | g) | Type the following: SELECT referenced_name FROM user_dependencies WHERE name = 'SCHOOL_API'; Analyze what you see and explain how it is useful. | h) | Type DESC school_api . What do you see? | i) | Explain what you are seeing. How is this different from the USER_DEPENDENCIES view? | 16.1.2 Enforce Purity Level with RESTRICT_REFERENCES Pragma Answer the following questions: a) | Add the following function to the school_api package specification that you created in Chapter 13: 6 FUNCTION total_cost_for_student 7 (i_student_id IN student.student_id%TYPE) 8 RETURN course.cost%TYPE; 9 END school_api; Append to the body: 60 FUNCTION total_cost_for_student 61 (i_student_id IN student.student_id%TYPE) 62 RETURN course.cost%TYPE 63 IS 64 v_cost course.cost%TYPE; 65 BEGIN 66 SELECT sum(cost) 67 INTO v_cost 68 FROM course c, section s, enrollment e 69 WHERE c.course_no = s.course_no 70 AND e.section_id = s.section_id 71 AND e.student_id = i_student_id; 72 RETURN v_cost; 73 EXCEPTION 74 WHEN OTHERS THEN 75 RETURN NULL; 76 END total_cost_for_student; 77 BEGIN 78 SELECT trunc(sysdate, 'DD') 79 INTO v_current_date 80 FROM dual; 81 END school_api; If you performed the following SELECT statement, what would you expect to see? SELECT school_api.total_cost_for_student(student_id), student_id FROM student; A pragma is a special directive to the PL/SQL compiler. You use the RESTRICT_REFERENCES pragma to tell the compiler about the purity level of a packaged function. To assert the purity level, use the syntax: PRAGMA RESTRICT_REFERENCES (function_name, WNDS [,WNPS], [,RNDS] [,RNPS]) | b) | Alter the package specification for school_api as follows : 6 FUNCTION total_cost_for_student 7 (i_student_id IN student.student_id%TYPE) 8 RETURN course.cost%TYPE; 9 PRAGMA RESTRICT_REFERENCES 10 (total_cost_for_student, WNDS, WNPS, RNPS); 11 END school_api; Now run the SELECT statement from question (a). What do you expect to see? | c) | What is the "purity level" of the function school_api. total_cost_for_student ? | d) | If you add the following three lines, will the package compile without error? 81 UPDATE STUDENT 82 SET employer = 'Prenctice Hall' 83 WHERE employer is null; 84 END school_api; | 16.1.3 Overload Modules When you overload modules, you give two or more modules the same name. The parameter lists of the modules must differ in a manner significant enough for the compiler (and runtime engine) to distinguish between the different versions. You can overload modules in three contexts: -
In a local module in the same PL/SQL block -
In a package specification -
In a package body a) | Add the following lines to the package specification of school_api . Then recompile the package specification. Explain what you have created. 11 PROCEDURE get_student_info 12 (i_student_id IN student.student_id%TYPE, 13 o_last_name OUT student.last_name%TYPE, 14 o_first_name OUT student.first_name%TYPE, 15 o_zip OUT student.zip%TYPE, 16 o_return_code OUT NUMBER); 17 PROCEDURE get_student_info 18 (i_last_name IN student.last_name%TYPE, 19 i_first_name IN student.first_name%TYPE, 20 o_student_id OUT student.student_id%TYPE, 21 o_zip OUT student.zip%TYPE, 22 o_return_code OUT NUMBER); 23 END school_api; | b) | Add the following code to the body of the package school_api . Explain what has been accomplished. 77 PROCEDURE get_student_info 78 (i_student_id IN student.student_id%TYPE, 79 o_last_name OUT student.last_name%TYPE, 80 o_first_name OUT student.first_name%TYPE, 81 o_zip OUT student.zip%TYPE, 82 o_return_code OUT NUMBER) 83 IS 84 BEGIN 85 SELECT last_name, first_name, zip 86 INTO o_last_name, o_first_name, o_zip 87 FROM student 88 WHERE student.student_id = i_student_id; 89 o_return_code := 0; 90 EXCEPTION 91 WHEN NO_DATA_FOUND 92 THEN 93 DBMS_OUTPUT.PUT_LINE ('Student ID is not valid.'); 94 o_return_code := -100; 95 o_last_name := NULL; 96 o_first_name := NULL; 97 o_zip := NULL; 98 WHEN OTHERS 99 THEN 100 DBMS_OUTPUT.PUT_LINE ('Error in procedure get_student_info'); 101 END get_student_info; 102 PROCEDURE get_student_info 103 (i_last_name IN student.last_name%TYPE, 104 i_first_name IN student.first_name%TYPE, 105 o_student_id OUT student.student_id%TYPE, 106 o_zip OUT student.zip%TYPE, 107 o_return_code OUT NUMBER) 108 IS 109 BEGIN 110 SELECT student_id, zip 111 INTO o_student_id, o_zip 112 FROM student 113 WHERE UPPER(last_name) = UPPER(i_last_name) 114 AND UPPER(first_name) = UPPER(i_first_name); 115 o_return_code := 0; 116 EXCEPTION 117 WHEN NO_DATA_FOUND 118 THEN 119 DBMS_OUTPUT.PUT_LINE ('Student name is not valid.'); 120 o_return_code := -100; 121 o_student_id := NULL; 122 o_zip := NULL; 123 WHEN OTHERS 124 THEN 125 DBMS_OUTPUT.PUT_LINE ('Error in procedure get_student_info'); 126 END get_student_info; 127 BEGIN 128 SELECT TRUNC(sysdate, 'DD') 129 INTO v_current_date 130 FROM dual; 131 END school_api; | c) | Write a PL/SQL block using the overloaded function you just created. | |