Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
254,14 KB
Nội dung
▼
Next, take a closer look at the second SELECT INTO statement. This statement uses CAST and
TABLE functions, which essentially enable you to query a nested table of objects as if it were a
regular table.
When run, this example produces the following output:
Zip: 00914
City: Santurce
State: PR
PL/SQL procedure successfully completed.
LAB 23.1 EXERCISES
This section provides exercises and suggested answers, with discussion related to how those answers
resulted.The most important thing to realize is whether your answer works.You should figure out the
implications of the answers and what the effects are of any different answers you may come up with.
23.1.1 Use Object Types
In this exercise, you continue exploring object types.
Complete the following tasks:
A) Create object type ENROLLMENT_OBJ_TYPE, which has the following attributes:
ATTRIBUTE NAME DATA TYPE PRECISION
student_id NUMBER 8
first_name VARCHAR2 25
last_name VARCHAR2 25
course_no NUMBER 8
section_no NUMBER 3
enroll_date DATE
final_grade NUMBER 3
ANSWER:
The creation script should look similar to the following:
ch23_1a.sql, version 1.0
CREATE OR REPLACE TYPE ENROLLMENT_OBJ_TYPE AS OBJECT
(student_id NUMBER(8),
first_name VARCHAR2(25),
last_name VARCHAR2(25),
course_no NUMBER(8),
section_no NUMBER(3),
enroll_date DATE,
final_grade NUMBER(3));
B)
The following script uses the newly created object type. Execute it and explain the output
produced.
ch23_2a.sql, version 1.0
SET SERVEROUTPUT ON
DECLARE
v_enrollment_obj enrollment_obj_type;
LAB 23.1
522
Lab 23.1 Exercises
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
BEGIN
v_enrollment_obj.student_id := 102;
v_enrollment_obj.first_name := 'Fred';
v_enrollment_obj.last_name := 'Crocitto';
v_enrollment_obj.course_no := 25;
END;
ANSWER:
The output of the script should look similar to the following:
DECLARE
*
ERROR at line 1:
ORA-06530: Reference to uninitialized composite
ORA-06512: at line 6
This version of the script causes an ORA-06530 error because it references individual attributes of
the uninitialized object type instance. Before the object attribute can be referenced, the object
must be initialized with the help of the constructor method.
C) Modify the script created in the preceding exercise (ch23_2a.sql) so that it does not produce an
ORA-06530 error.
ANSWER: The script should look similar to the following. Changes are shown in bold.
ch23_2b.sql, version 2.0
SET SERVEROUTPUT ON
DECLARE
v_enrollment_obj enrollment_obj_type;
BEGIN
v_enrollment_obj :=
enrollment_obj_type(102, 'Fred', 'Crocitto', 25, null, null,
null);
END;
D)
Modify this script (ch23_2b.sql) so that all object attributes are populated with corresponding
values selected from the appropriate tables.
ANSWER: The script should look similar to one of the following scripts. Changes are shown
in bold.
The first version of the script employs the SELECT INTO statement along with the constructor to
initialize other attributes as well. Note that the SELECT INTO statement specifies WHERE criteria for
the SECTION_NO in addition to the criteria for the STUDENT_ID and COURSE_NO.This ensures
that the SELECT INTO statement does not cause an
ORA-01422: exact fetch returns
more than requested number of rows
error.
ch23_2c.sql, version 3.0
SET SERVEROUTPUT ON
DECLARE
v_enrollment_obj enrollment_obj_type;
BEGIN
SELECT
enrollment_obj_type(st.student_id, st.first_name, st.last_name,
c.course_no, se.section_no, e.enroll_date,
e.final_grade)
INTO v_enrollment_obj
LAB 23.1
Lab 23.1 Exercises
523
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
FROM student st, course c, section se, enrollment e
WHERE st.student_id = e.student_id
AND c.course_no = se.course_no
AND se.section_id = e.section_id
AND st.student_id = 102
AND c.course_no = 25
AND se.section_no = 2;
END;
The SELECT statement in the preceding script can be modified according to the ANSI 1999 SQL
standard:
SELECT enrollment_obj_type(st.student_id, st.first_name,
st.last_name, c.course_no, se.section_no,
e.enroll_date, e.final_grade)
INTO v_enrollment_obj
FROM enrollment e
JOIN student st
ON e.student_id = st.student_id
JOIN section se
ON e.section_id = se.section_id
JOIN course c
ON se.course_no = c.course_no
WHERE st.student_id = 102
AND c.course_no = 25
AND se.section_no = 2;
The preceding SELECT statement uses the ON syntax to specify the join condition between four
tables.This type of join becomes especially useful when the columns participating in the join do
not have the same name.
BY THE WAY
You will find detailed explanations and examples of the statements using the new ANSI 1999 SQL
standard in Appendix C and in the Oracle help. Throughout this book we have tried to provide you
with examples illustrating both standards; however, our main focus has remained on PL/SQL features
rather than SQL.
The second version of the script uses a cursor FOR loop. This approach eliminates the need for
additional criteria against the SECTION_NO.
ch23_2d.sql, version 4.0
SET SERVEROUTPUT ON
DECLARE
v_enrollment_obj enrollment_obj_type;
BEGIN
FOR REC IN (SELECT st.student_id, st.first_name, st.last_name,
c.course_no, se.section_no, e.enroll_date,
e.final_grade
FROM student st, course c, section se, enrollment e
WHERE st.student_id = e.student_id
AND c.course_no = se.course_no
LAB 23.1
524
Lab 23.1 Exercises
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
AND se.section_id = e.section_id
AND st.student_id = 102
AND c.course_no = 25)
LOOP
v_enrollment_obj :=
enrollment_obj_type(rec.student_id, rec.first_name,
rec.last_name, rec.course_no,
rec.section_no, rec.enroll_date,
rec.final_grade);
END LOOP;
END;
E)
Modify one of the scripts created in the previous exercises (use either ch23_2c.sql or ch23_2d.sql)
so that attribute values are displayed on the screen.
ANSWER: The script should look similar to the following. All changes are shown in bold.
ch23_2e.sql, version 5.0
SET SERVEROUTPUT ON
DECLARE
v_enrollment_obj enrollment_obj_type;
BEGIN
FOR REC IN (SELECT st.student_id, st.first_name, st.last_name,
c.course_no, se.section_no, e.enroll_date,
e.final_grade
FROM student st, course c, section se, enrollment e
WHERE st.student_id = e.student_id
AND c.course_no = se.course_no
AND se.section_id = e.section_id
AND st.student_id = 102
AND c.course_no = 25)
LOOP
v_enrollment_obj :=
enrollment_obj_type(rec.student_id, rec.first_name,
rec.last_name, rec.course_no,
rec.section_no, rec.enroll_date,
rec.final_grade);
DBMS_OUTPUT.PUT_LINE ('student_id: '||
v_enrollment_obj.student_id);
DBMS_OUTPUT.PUT_LINE ('first_name: '||
v_enrollment_obj.first_name);
DBMS_OUTPUT.PUT_LINE ('last_name: '||
v_enrollment_obj.last_name);
DBMS_OUTPUT.PUT_LINE ('course_no: '||
v_enrollment_obj.course_no);
DBMS_OUTPUT.PUT_LINE ('section_no: '||
v_enrollment_obj.section_no);
DBMS_OUTPUT.PUT_LINE ('enroll_date: '||
v_enrollment_obj.enroll_date);
LAB 23.1
Lab 23.1 Exercises
525
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
DBMS_OUTPUT.PUT_LINE ('final_grade: '||
v_enrollment_obj.final_grade);
END LOOP;
END;
This version of the script produces the following output:
student_id: 102
first_name: Fred
last_name: Crocitto
course_no: 25
section_no: 2
enroll_date: 30-JAN-07
final_grade:
student_id: 102
first_name: Fred
last_name: Crocitto
course_no: 25
section_no: 5
enroll_date: 30-JAN-07
final_grade: 92
PL/SQL procedure successfully completed.
23.1.2
Use Object Types with Collections
In this exercise, you continue exploring how object types may be used with collections.
Complete the following tasks:
A) Modify script ch23_2e.sql, created in the preceding exercise. In the new version of the script,
populate an associative array of objects. Use multiple student IDs for this exercise—102, 103,
and 104.
ANSWER: The script should look similar to the following:
ch23_3a.sql, version 1.0
SET SERVEROUTPUT ON
DECLARE
TYPE enroll_tab_type IS TABLE OF enrollment_obj_type
INDEX BY BINARY_INTEGER;
v_enrollment_tab enroll_tab_type;
v_counter integer := 0;
BEGIN
FOR REC IN (SELECT st.student_id, st.first_name, st.last_name,
c.course_no, se.section_no, e.enroll_date,
e.final_grade
FROM student st, course c, section se, enrollment e
WHERE st.student_id = e.student_id
AND c.course_no = se.course_no
AND se.section_id = e.section_id
AND st.student_id in (102, 103, 104))
LAB 23.1
526
Lab 23.1 Exercises
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
LOOP
v_counter := v_counter + 1;
v_enrollment_tab(v_counter) :=
enrollment_obj_type(rec.student_id, rec.first_name,
rec.last_name, rec.course_no,
rec.section_no, rec.enroll_date,
rec.final_grade);
DBMS_OUTPUT.PUT_LINE ('student_id: '||
v_enrollment_tab(v_counter).student_id);
DBMS_OUTPUT.PUT_LINE ('first_name: '||
v_enrollment_tab(v_counter).first_name);
DBMS_OUTPUT.PUT_LINE ('last_name: '||
v_enrollment_tab(v_counter).last_name);
DBMS_OUTPUT.PUT_LINE ('course_no: '||
v_enrollment_tab(v_counter).course_no);
DBMS_OUTPUT.PUT_LINE ('section_no: '||
v_enrollment_tab(v_counter).section_no);
DBMS_OUTPUT.PUT_LINE ('enroll_date: '||
v_enrollment_tab(v_counter).enroll_date);
DBMS_OUTPUT.PUT_LINE ('final_grade: '||
v_enrollment_tab(v_counter).final_grade);
DBMS_OUTPUT.PUT_LINE (' ');
END LOOP;
END;
The preceding script defines an associative array of objects that is populated with the help of the
cursor FOR loop. After a single row of the associative array has been initialized, it is displayed on
the screen.
Take a closer look at how each row of the associative array is initialized:
v_enrollment_tab(v_counter) :=
enrollment_obj_type(rec.student_id, rec.first_name,
rec.last_name, rec.course_no,
rec.section_no, rec.enroll_date,
rec.final_grade);
A row is referenced by a subscript. In this case it is a variable, v_counter. Because each row
represents an object instance, it is initialized by referencing the default constructor method asso-
ciated with the corresponding object type.
When run, the script produces the following output:
student_id: 102
first_name: Fred
last_name: Crocitto
course_no: 25
section_no: 2
enroll_date: 30-JAN-07
final_grade:
LAB 23.1
Lab 23.1 Exercises
527
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
student_id: 102
first_name: Fred
last_name: Crocitto
course_no: 25
section_no: 5
enroll_date: 30-JAN-07
final_grade: 92
student_id: 103
first_name: J.
last_name: Landry
course_no: 20
section_no: 2
enroll_date: 30-JAN-07
final_grade:
student_id: 104
first_name: Laetia
last_name: Enison
course_no: 20
section_no: 2
enroll_date: 30-JAN-07
final_grade:
PL/SQL procedure successfully completed.
B)
Modify the script so that the table of objects is populated using the BULK SELECT INTO statement.
ANSWER: The script should look similar to the following. Changes are shown in bold.
ch23_3b.sql, version 2.0
SET SERVEROUTPUT ON
DECLARE
TYPE enroll_tab_type IS TABLE OF enrollment_obj_type
INDEX BY BINARY_INTEGER;
v_enrollment_tab enroll_tab_type;
BEGIN
SELECT
enrollment_obj_type(st.student_id, st.first_name, st.last_name,
c.course_no, se.section_no, e.enroll_date,
e.final_grade)
BULK COLLECT INTO v_enrollment_tab
FROM student st, course c, section se, enrollment e
WHERE st.student_id = e.student_id
AND c.course_no = se.course_no
AND se.section_id = e.section_id
AND st.student_id in (102, 103, 104);
FOR i IN 1 v_enrollment_tab.COUNT
LOOP
LAB 23.1
528
Lab 23.1 Exercises
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
DBMS_OUTPUT.PUT_LINE ('student_id: '||
v_enrollment_tab(i).student_id);
DBMS_OUTPUT.PUT_LINE ('first_name: '||
v_enrollment_tab(i).first_name);
DBMS_OUTPUT.PUT_LINE ('last_name: '||
v_enrollment_tab(i).last_name);
DBMS_OUTPUT.PUT_LINE ('course_no: '||
v_enrollment_tab(i).course_no);
DBMS_OUTPUT.PUT_LINE ('section_no: '||
v_enrollment_tab(i).section_no);
DBMS_OUTPUT.PUT_LINE ('enroll_date: '||
v_enrollment_tab(i).enroll_date);
DBMS_OUTPUT.PUT_LINE ('final_grade: '||
v_enrollment_tab(i).final_grade);
DBMS_OUTPUT.PUT_LINE (' ');
END LOOP;
END;
In this version of the script, the cursor FOR loop has been replaced by the BULK SELECT INTO
statement. As a result, the cursor FOR loop is replaced by the numeric FOR loop to display data on
the screen.These changes eliminate the need for the variable v_counter, which was used to
reference individual rows of the associative array.
When run, this version of the script produces output that is identical to the previous version.
C) Modify the script so that data stored in the table of objects can be retrieved using the SELECT
INTO statement as well.
ANSWER: As mentioned previously, for you to select data from a table of objects, the underlying
table type must be either a nested table or a varray that is created and stored in the database
schema.This is accomplished by the following statement:
CREATE OR REPLACE TYPE enroll_tab_type AS TABLE OF
enrollment_obj_type;
/
After the nested table type is created, the script is modified as follows. Changes are shown in bold.
ch23_3c.sql, version 3.0
SET SERVEROUTPUT ON
DECLARE
v_enrollment_tab enroll_tab_type;
BEGIN
SELECT
enrollment_obj_type(st.student_id, st.first_name, st.last_name,
c.course_no, se.section_no, e.enroll_date,
e.final_grade)
BULK COLLECT INTO v_enrollment_tab
FROM student st, course c, section se, enrollment e
WHERE st.student_id = e.student_id
AND c.course_no = se.course_no
AND se.section_id = e.section_id
AND st.student_id in (102, 103, 104);
LAB 23.1
Lab 23.1 Exercises
529
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
FOR rec IN (SELECT *
FROM TABLE(CAST(v_enrollment_tab AS
enroll_tab_type)))
LOOP
DBMS_OUTPUT.PUT_LINE ('student_id: '||rec.student_id);
DBMS_OUTPUT.PUT_LINE ('first_name: '||rec.first_name);
DBMS_OUTPUT.PUT_LINE ('last_name: '||rec.last_name);
DBMS_OUTPUT.PUT_LINE ('course_no: '||rec.course_no);
DBMS_OUTPUT.PUT_LINE ('section_no: '||rec.section_no);
DBMS_OUTPUT.PUT_LINE ('enroll_date: '||rec.enroll_date);
DBMS_OUTPUT.PUT_LINE ('final_grade: '||rec.final_grade);
DBMS_OUTPUT.PUT_LINE (' ');
END LOOP;
END;
Note that in this version of the script, the numeric FOR loop is replaced by the cursor FOR loop
against the nested table of objects. Note that the DBMS_OUTPUT.PUT_LINE statements are also
changed so that they reference records returned by the cursor.
LAB 23.1
530
Lab 23.1 Exercises
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
LAB 23.2
Object Type Methods
LAB OBJECTIVE
After completing this lab, you will be able to
.
Use object type methods
In Lab 23.1 you learned that object type methods are functions and procedures that specify
actions that may be performed on the object type attributes and that they are defined in the
object type specification. You also have seen how to use default system-defined constructor
methods. The constructor is only one of the method types that PL/SQL supports. Some other
method types are member, static, map, and order. The method type typically is determined by
the actions that a particular method performs. For example, constructor methods are used to
initialize object instances, and map and order methods are used to compare and sort object
instances.
Often object type methods use a built-in parameter called SELF. This parameter represents a
particular instance of the object type. As such, it is available to the methods that are invoked on
that object type instance. You will see various examples of the SELF parameter in the following
discussions.
CONSTRUCTOR METHODS
As discussed previously, a constructor method is a default method that is implicitly created by
the system whenever a new object type is created. It is a function that has the same name as its
object type. Its input parameters have the same names and datatypes as the object type attrib-
utes and are listed in the same order as the object type attributes. The constructor method
returns a new instance of the object type. In other words, it initializes a new object instance and
assigns values to the object attributes. Consider the following code fragments, which illustrate
calls to the default constructor method for the zipcode_obj_type created earlier:
FOR EXAMPLE
zip_obj1 := ZIPCODE_OBJ_TYPE('00914', 'Santurce', 'PR', USER, SYSDATE,
USER, SYSDATE);
or
zip_obj2 := ZIPCODE_OBJ_TYPE(NULL, NULL, NULL, NULL, NULL,
NULL NULL);
LAB 23.2
531
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... www.verypdf.com to remove this watermark CHAPTER 24 Oracle Supplied Packages CHAPTER OBJECTIVES In this chapter, you will learn about Making use of Oracle- supplied packages to profile PL/SQL, access files, and schedule jobs Making use of Oracle- supplied packages to generate an explain plan and create HTML pages Creating Web pages with the Oracle Web Toolkit Oracle has built into the Database more than... Oracle Supplied Packages to Profile PL/SQL, Access Files, and Schedule Jobs LAB OBJECTIVES After completing this lab, you will be able to Access files with UTL_FILE Schedule jobs with DBMS_JOB Submit jobs PROFILE PL/SQL WITH DBMS_HPROF In Oracle 11g the package for PL/SQL profiling known previously as DBMS_PROFILER was extended The Hierarchical Profiler expands DBMS_PROFILER through DBMS_HPROF by. .. do with ordinary PL/SQL packages This means that Oracle- supplied packages have full access to the operating system and other aspects of the Oracle Server that are not available to ordinary PL/SQL packages You are already familiar with the DBMS_OUTPUT package’s procedure PUT_LINE, which is used to gather debugging information into the buffer for output This chapter introduces a few key Oracle supplied... extend what you can achieve with PL/SQL Usually, each new version of the database comes with new supplied packages Oracle introduced about 17 new packages in each upgrade to versions 9.2 and 10.0 Oracle 11g had 45 new packages and eight that were updated These packages offer functionality that you would not be able to achieve with PL/SQL alone The reason is that the Oracle- supplied packages use the... parameters by their position in the header of the function, procedure, or, in this case, constructor Next, consider the call to the default constructor method that uses named notation Note that in this case, the order of parameters does not correspond to the order of the attributes in zipcode_obj_type Instead, they are referenced by their names: FOR EXAMPLE zip_obj3 := ZIPCODE_OBJ_TYPE(created _by created_date... parameters that represent complex datatypes such as collections, records, and object type instances, the copying step can add significant processing overhead By adding a NOCOPY hint, you instruct the PL/SQL compiler to pass OUT and IN OUT parameters by reference and eliminate the copying step Next, both constructor methods populate the city, state, and zip attributes Note how these attributes are referenced... your stored PL/SQL code The Profiler indicates how many times each line of code is executed, how long it is executed, and other information The DBMS_HPROF package is installed by default To use it, the DBA must grant execute privileges on the package to the appropriate users and provide a directory on the server to write the profile information to This will be a text file You can do this by connecting... important to note that even though this method references data associated with some object instance, this object instance is created elsewhere (such as in another PL/SQL script, function, or procedure) and then passed into this method COMPARING OBJECTS In PL/SQL, element datatypes such as VARCH AR2, NUMBER, and DATE have a predefined order that enables them to be compared to each other or sorted For example,... method is a member function that does not accept any parameters and returns an element datatype, as demonstrated in the following example: FOR EXAMPLE CREATE OR REPLACE (zip city state created _by created_date modified _by modified_date TYPE zipcode_obj_type AS OBJECT VARCHAR2(5), VARCHAR2(25), VARCHAR2(2), VARCHAR2(30), DATE, VARCHAR2(30), DATE, CONSTRUCTOR FUNCTION zipcode_obj_type (SELF IN OUT NOCOPY ZIPCODE_OBJ_TYPE,... as its return type Furthermore, the method must return a negative number, 0, or a positive number This number indicates that the object instance referenced by the SELF parameter is less than, equal to, or greater than the object instance referenced by the IN parameter DID YOU KNOW? The map and order methods have the following restrictions: An object type may contain either an order or map method An . Instead,
they are referenced by their names:
FOR EXAMPLE
zip_obj3 := ZIPCODE_OBJ_TYPE(created _by => USER,
created_date => SYSDATE,
modified _by => USER,
modified_date. significant processing overhead. By adding a NOCOPY hint,
you instruct the PL/SQL compiler to pass OUT and IN OUT parameters by reference and elim-
inate the