1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Oracle PL/SQL by Example- P8 pptx

50 364 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 50
Dung lượng 257,57 KB

Nội dung

DID YOU KNOW? What is the difference between a NULL collection and an empty collection? If a collection has not been initialized, referencing its individual elements causes the following error: DECLARE TYPE integer_type IS TABLE OF INTEGER; integer_tab integer_type; v_counter integer := 1; BEGIN DBMS_OUTPUT.PUT_LINE (integer_tab(v_counter)); END; DECLARE * ERROR at line 1: ORA-06531: Reference to uninitialized collection ORA-06512: at line 7 If a collection has been initialized so that it is empty, referencing its individual elements causes a different error: DECLARE TYPE integer_type IS TABLE OF INTEGER; integer_tab integer_type := integer_type(); v_counter integer := 1; BEGIN DBMS_OUTPUT.PUT_LINE (integer_tab(v_counter)); END; DECLARE * ERROR at line 1: ORA-06533: Subscript beyond count ORA-06512: at line 7 COLLECTION METHODS In the previous examples, you have seen one of the collection methods, EXTEND. A collection method is a built-in function that is called using dot notation as follows: collection_name . method_name The following list explains collection methods that allow you to manipulate or gain information about a particular collection: . EXISTS returns TRUE if a specified element exists in a collection. This method can be used to avoid SUBSCRIPT_OUTSIDE_LIMIT exceptions. . COUNT returns the total number of elements in a collection. LAB 15.1 322 PL/SQL Tables Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. . EXTEND increases the size of a collection. . DELETE deletes either all elements, elements in the specified range, or a particular element from a collection. Note that PL/SQL keeps placeholders of the deleted elements. . FIRST and LAST return subscripts of the first and last elements of a collection. Note that if the first elements of a nested table are deleted, the FIRST method returns a value greater than 1. If elements have been deleted from the middle of a nested table, the LAST method returns a value greater than the COUNT method. . PRIOR and NEXT return subscripts that precede and succeed a specified collection subscript. . TRIM removes either one or a specified number of elements from the end of a collection. Note that PL/SQL does not keep placeholders for the trimmed elements. BY THE WAY EXTEND and TRIM methods cannot be used with index-by tables. Consider the following example, which illustrates the use of various collection methods: FOR EXAMPLE DECLARE TYPE index_by_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; index_by_table index_by_type; TYPE nested_type IS TABLE OF NUMBER; nested_table nested_type := nested_type(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); BEGIN Populate index by table FOR i IN 1 10 LOOP index_by_table(i) := i; END LOOP; IF index_by_table.EXISTS(3) THEN DBMS_OUTPUT.PUT_LINE ('index_by_table(3) = '||index_by_table(3)); END IF; delete 10th element from a collection nested_table.DELETE(10); delete elements 1 through 3 from a collection nested_table.DELETE(1,3); index_by_table.DELETE(10); LAB 15.1 PL/SQL Tables 323 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. FOR EXAMPLE (continued) DBMS_OUTPUT.PUT_LINE ('nested_table.COUNT = '||nested_table.COUNT); DBMS_OUTPUT.PUT_LINE ('index_by_table.COUNT = '|| index_by_table.COUNT); DBMS_OUTPUT.PUT_LINE ('nested_table.FIRST = '||nested_table.FIRST); DBMS_OUTPUT.PUT_LINE ('nested_table.LAST = '||nested_table.LAST); DBMS_OUTPUT.PUT_LINE ('index_by_table.FIRST = '|| index_by_table.FIRST); DBMS_OUTPUT.PUT_LINE ('index_by_table.LAST = '||index_by_table.LAST); DBMS_OUTPUT.PUT_LINE ('nested_table.PRIOR(2) = '|| nested_table. PRIOR(2)); DBMS_OUTPUT.PUT_LINE ('nested_table.NEXT(2) = '|| nested_table.NEXT(2)); DBMS_OUTPUT.PUT_LINE ('index_by_table.PRIOR(2) = '|| index_by_table.PRIOR(2)); DBMS_OUTPUT.PUT_LINE ('index_by_table.NEXT(2) = '|| index_by_table.NEXT(2)); Trim last two elements nested_table.TRIM(2); Trim last element nested_table.TRIM; DBMS_OUTPUT.PUT_LINE('nested_table.LAST = '||nested_table.LAST); END; Consider the output returned by this example: index_by_table(3) = 3 nested_table.COUNT = 6 index_by_table.COUNT = 9 nested_table.FIRST = 4 nested_table.LAST = 9 index_by_table.FIRST = 1 index_by_table.LAST = 9 nested_table.PRIOR(2) = nested_table.NEXT(2) = 4 index_by_table.PRIOR(2) = 1 index_by_table.NEXT(2) = 3 nested_table.LAST = 7 PL/SQL procedure successfully completed. LAB 15.1 324 PL/SQL Tables Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. The first line of the output index_by_table(3) = 3 is produced because the EXISTS method returns TRUE. As a result, the IF statement IF index_by_table.EXISTS(3) THEN DBMS_OUTPUT.PUT_LINE ('index_by_table(3) = '||index_by_table(3)); END IF; evaluates to TRUE as well. The second and third lines of the output nested_table.COUNT = 6 index_by_table.COUNT = 9 show the results of method COUNT after some elements were deleted from the associative array and nested table. Next, lines four through seven of the output nested_table.FIRST = 4 nested_table.LAST = 9 index_by_table.FIRST = 1 index_by_table.LAST = 9 show the results of the FIRST and LAST methods. Notice that the FIRST method applied to the nested table returns 4 because the first three elements were deleted earlier. Next, lines eight through eleven of the output nested_table.PRIOR(2) = nested_table.NEXT(2) = 4 index_by_table.PRIOR(2) = 1 index_by_table.NEXT(2) = 3 show the results of the PRIOR and NEXT methods. Notice that the PRIOR method applied to the nested table returns NULL because the first element was deleted earlier. Finally, the last line of the output nested_table.LAST = 7 shows the value of the last subscript after the last three elements were removed. As mentioned earlier, as soon as the DELETE method is issued, PL/SQL keeps placeholders of the deleted elements. Therefore, the first call of the TRIM method removes the ninth and tenth elements of the nested table, and the second call of the TRIM method removes the eighth element of the nested table. As a result, the LAST method returns value 7 as the last subscript of the nested table. LAB 15.1 PL/SQL Tables 325 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. ▼ LAB 15.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. 15.1.1 Use Associative Arrays In this exercise, you learn more about associative arrays. Create the following PL/SQL script: ch15_1a.sql, version 1.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; TYPE course_type IS TABLE OF course.description%TYPE INDEX BY BINARY_INTEGER; course_tab course_type; v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab(v_counter) := course_rec.description; END LOOP; END; Answer the following questions, and complete the following tasks: A) Explain the preceding script. ANSWER: The declaration section of the script defines the associative array type, course_type.This type is based on the column DESCRIPTION of the table COURSE. Next, the actual associative array is declared as course_tab. The executable section of the script populates the course_tab table in the cursor FOR loop. Each element of the associative array is referenced by its subscript, v_counter. For each itera- tion of the loop, the value of v_counter is incremented by 1 so that each new description value is stored in the new row of the associative array. B) Modify the script so that rows of the associative array are displayed on the screen. ANSWER: The script should look similar to the following. Changes are shown in bold. ch15_1b.sql, version 2.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; LAB 15.1 326 Lab 15.1 Exercises Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. TYPE course_type IS TABLE OF course.description%TYPE INDEX BY BINARY_INTEGER; course_tab course_type; v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab(v_counter):= course_rec.description; DBMS_OUTPUT.PUT_LINE('course('||v_counter||'): '|| course_tab(v_counter)); END LOOP; END; Consider another version of the same script: ch15_1c.sql, version 3.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; TYPE course_type IS TABLE OF course.description%TYPE INDEX BY BINARY_INTEGER; course_tab course_type; v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab(v_counter):= course_rec.description; END LOOP; FOR i IN 1 v_counter LOOP DBMS_OUTPUT.PUT_LINE('course('||i||'): '||course_tab(i)); END LOOP; END; When run, both versions produce the same output: course(1): DP Overview course(2): Intro to Computers course(3): Intro to Programming course(4): Structured Programming Techniques course(5): Hands-On Windows course(6): Intro to Java Programming course(7): Intermediate Java Programming course(8): Advanced Java Programming course(9): JDeveloper course(10): Intro to Unix course(11): Basics of Unix Admin course(12): Advanced Unix Admin LAB 15.1 Lab 15.1 Exercises 327 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. course(13): Unix Tips and Techniques course(14): Structured Analysis course(15): Project Management course(16): Database Design course(17): Internet Protocols course(18): Java for C/C++ Programmers course(19): GUI Programming course(20): Intro to SQL course(21): Oracle Tools course(22): PL/SQL Programming course(23): Intro to Internet course(24): Intro to the Basic Language course(25): Operating Systems course(26): Network Administration course(27): JDeveloper Lab course(28): Database System Principles course(29): JDeveloper Techniques course(30): DB Programming in Java PL/SQL procedure successfully completed. C) Modify the script so that only first and last rows of the associative array are displayed on the screen. ANSWER: The script should look similar to the following. Changes are shown in bold. ch15_1d.sql, version 4.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; TYPE course_type IS TABLE OF course.description%TYPE INDEX BY BINARY_INTEGER; course_tab course_type; v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab(v_counter) := course_rec.description; END LOOP; DBMS_OUTPUT.PUT_LINE('course('||course_tab.FIRST||'): '|| course_tab(course_tab.FIRST)); DBMS_OUTPUT.PUT_LINE('course('||course_tab.LAST||'): '|| course_tab(course_tab.LAST)); END; Consider the statements course_tab(course_tab.FIRST) LAB 15.1 328 Lab 15.1 Exercises Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. and course_tab(course_tab.LAST) used in this example. Although these statements look somewhat different from the statements you have seen so far, they produce the same effect as the course_tab(1) and course_tab(30) statements. As mentioned earlier, the FIRST and LAST methods return the subscripts of the first and last elements of a collection, respectively. In this example, the associative array contains 30 elements, where the first element has a subscript of 1, and the last element has a subscript of 30. This version of the script produces the following output: course(1): DP Overview course(30): DB Programming in Java PL/SQL procedure successfully completed. D) Modify the script by adding the following statements, and explain the output produced: I) Display the total number of elements in the associative array after it has been populated on the screen. II) Delete the last element, and display the total number of elements of the associative array again. III) Delete the fifth element, and display the total number of elements and the subscript of the last element of the associative array again. ANSWER: The script should look similar to the following. All changes are shown in bold. ch15_1e.sql, version 5.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; TYPE course_type IS TABLE OF course.description%TYPE INDEX BY BINARY_INTEGER; course_tab course_type; v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab(v_counter) := course_rec.description; END LOOP; Display the total number of elements in the associative array DBMS_OUTPUT.PUT_LINE ('1. Total number of elements: '|| course_tab.COUNT); LAB 15.1 Lab 15.1 Exercises 329 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Delete the last element of the associative array Display the total number of elements in the associative array course_tab.DELETE(course_tab.LAST); DBMS_OUTPUT.PUT_LINE ('2. Total number of elements: '|| course_tab.COUNT); Delete the fifth element of the associative array Display the total number of elements in the associative array Display the subscript of the last element of the associative array course_tab.DELETE(5); DBMS_OUTPUT.PUT_LINE ('3. Total number of elements: '|| course_tab.COUNT); DBMS_OUTPUT.PUT_LINE ('3. The subscript of the last element: '|| course_tab.LAST); END; When run, this example produces the following output: 1. Total number of elements: 30 2. Total number of elements: 29 3. Total number of elements: 28 3. The subscript of the last element: 29 PL/SQL procedure successfully completed. First, the total number of elements in the associative array is calculated using the COUNT method and displayed on the screen. Second, the last element is deleted using the DELETE and LAST methods, and the total number of elements in the associative array is displayed on the screen again.Third, the fifth element is deleted, and the total number of elements in the associative array and the subscript of the last element are displayed on the screen. Consider the last two lines of output. After the fifth element of the associative array is deleted, the COUNT method returns the value 28, and the LAST method returns the value 29. Usually, the values returned by the COUNT and LAST methods are equal. However, when an element is deleted from the middle of the associative array, the value returned by the LAST method is greater than the value returned by the COUNT method, because the LAST method ignores deleted elements. 15.1.2 Use Nested Tables In this exercise, you learn more about nested tables. Complete the following tasks: A) Modify script ch15_1a.sql, used in Exercise 15.1.1. Instead of using an associative array, use a nested table. ANSWER: The script should look similar to the following. Changes are shown in bold. ch15_2a.sql, version 1.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; LAB 15.1 330 Lab 15.1 Exercises Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. TYPE course_type IS TABLE OF course.description%TYPE; course_tab course_type := course_type(); v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab.EXTEND; course_tab(v_counter) := course_rec.description; END LOOP; END; B) Modify the script by adding the following statements, and explain the output produced: I) Delete the last element of the nested table, and then assign a new value to it. Execute the script. II) Trim the last element of the nested table, and then assign a new value to it. Execute the script. ANSWER: I) The script should look similar to the following. Changes are shown in bold. ch15_2b.sql, version 2.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; TYPE course_type IS TABLE OF course.description%TYPE; course_tab course_type := course_type(); v_counter INTEGER := 0; BEGIN FOR course_rec IN course_cur LOOP v_counter := v_counter + 1; course_tab.EXTEND; course_tab(v_counter) := course_rec.description; END LOOP; course_tab.DELETE(30); course_tab(30) := 'New Course'; END; II) The script should look similar to the following. Changes are shown in bold. ch15_2c.sql, version 3.0 SET SERVEROUTPUT ON DECLARE CURSOR course_cur IS SELECT description FROM course; LAB 15.1 Lab 15.1 Exercises 331 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... LOOP extend the size of varray by 1 and copy the current element to the last element city_varray.EXTEND(1, i); END LOOP; Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Lab 15.2 Exercises LAB 15.2 341 In this loop, the loop counter is implicitly incremented by 1 So for the first iteration of the loop, the size of the varray is increased by 1, and the first element of... 15.3.1 Use Multilevel Collections In this exercise, you learn more about multilevel collections Create the following PL/SQL script: ch15_4a.sql, version 1.0 SET SERVEROUTPUT ON DECLARE TYPE table_type1 IS TABLE OF INTEGER INDEX BY BINARY_INTEGER; TYPE table_type2 IS TABLE OF TABLE_TYPE1 INDEX BY BINARY_INTEGER; table_tab1 table_type1; table_tab2 table_type2; BEGIN FOR i IN 1 2 LOOP FOR j IN 1 3 LOOP IF... Date: 17-FEB-03 Name: Yvonne Winnicki Registration Date: 17-FEB-03 Name: Mike Madej Registration Date: 17-FEB-03 PL/SQL procedure successfully completed Note that because a cursor-based record is defined based on the rows returned by a cursor’s select statement, its declaration must be preceded by a cursor declaration In other words, a cursor-based record is dependent on a particular cursor and cannot... incomplete or malformed ORA-06550: line 2, column 16: PL/SQL: Item ignored ORA-06550: line 12, column 30: PLS-00320: the declaration of the type incomplete or malformed ORA-06550: line 12, column 7: PL/SQL: SQL Statement ignored ORA-06550: line 16, column 10: PLS-00320: the declaration of the type incomplete or malformed ORA-06550: line 15, column 7: PL/SQL: Statement ignored ORA-06550: line 17, column... Haven PL/SQL procedure successfully completed Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark LAB 15.3 342 LAB 15.3 Multilevel Collections LAB OBJECTIVE After completing this lab, you will be able to Use multilevel collections So far you have seen various examples of collections with the element type based on a scalar type, such as NUMBER and VARCHAR2 Starting with Oracle. .. variations of the type, VARRAY and VARYING ARRAY A size_limit is a positive integer literal that specifies the upper bound of a varray As in the case of PL/SQL tables, restrictions apply to an element_type of a varray These restrictions are listed in the online Oracle help Second, the actual varray is declared based on the type specified in the first step Consider the following code fragment: FOR EXAMPLE... DBMS_OUTPUT.PUT_LINE('varray.LAST = '||varray.LAST); END; Consider the output returned by this example: varray.COUNT = 6 varray.LIMIT = 10 varray.FIRST = 1 varray.LAST = 6 varray.LAST = 8 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Varrays LAB 15.2 337 varray(8) = 4 varray.LAST = 6 PL/SQL procedure successfully completed The first two lines of output varray.COUNT = 6... using the DELETE method As mentioned earlier, when the DELETE method is used, PL/SQL keeps a placeholder of the deleted element Therefore, the statement course_tab(30) := 'New Course'; does not cause any errors In the current version of the script, the last element of the nested table is removed using the TRIM method In this case, PL/SQL does not keep a placeholder of the trimmed element, because the TRIM... or malformed ORA-06550: line 17, column 7: PL/SQL: Statement ignored of this expression is of this expression is of this expression is of this expression is USER-DEFINED RECORDS So far, you have seen how to create records based on a table or cursor However, you may need to create a record that is not based on any table or any one cursor For such situations, PL/SQL provides a user-defined record type... '||sample_rec.field1); DBMS_OUTPUT.PUT_LINE ('sample_rec.field2 = '||sample_rec.field2); END; The output is as follows: sample_rec.field1 = 10 sample_rec.field2 = ABC PL/SQL procedure successfully completed RECORD COMPATIBILITY You have seen that a record is defined by its name, structure, and type However, it is important to realize that two records may have the same structure yet be of a different type As a result, . methods: FOR EXAMPLE DECLARE TYPE index _by_ type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; index _by_ table index _by_ type; TYPE nested_type IS TABLE OF NUMBER; nested_table. Populate index by table FOR i IN 1 10 LOOP index _by_ table(i) := i; END LOOP; IF index _by_ table.EXISTS(3) THEN DBMS_OUTPUT.PUT_LINE ('index _by_ table(3)

Ngày đăng: 21/01/2014, 08:20

TỪ KHÓA LIÊN QUAN