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
203,6 KB
Nội dung
FUNCTION LAST RETURN BINARY_INTEGER; Example IF my_list.EXISTS(my_list.FIRST) THEN my_list(my_list.FIRST) := 42; ELSE my_list.EXTEND; my_list(my_list.FIRST) := 42; END IF; Returns FIRST returns the lowest index in use in the collection; LAST returns the highest. Applies to Nested tables, index-by tables, VARRAYs. Boundary considerations FIRST and LAST return NULL when applied to initialized collections which have no elements. For VARRAYs which have at least one element, FIRST is always 1, and LAST is always equal to COUNT. Exceptions possible If applied to an uninitialized nested table or a VARRAY, raises COLLECTION_IS_NULL predefined exception. 19.6.6 LIMIT Specification FUNCTION LIMIT RETURN BINARY_INTEGER; Example IF my_list.LAST < my_list.LIMIT THEN my_list.EXTEND; END IF; Returns Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. The maximum number of elements that is possible for a given VARRAY. Applies to VARRAYs only. Returns NULL if applied to nested tables or index-by tables. Boundary considerations None Exceptions possible If applied to an uninitialized nested table or a VARRAY, raises COLLECTION_IS_NULL predefined exception. 19.6.7 PRIOR(i), NEXT(i) Specification FUNCTION PRIOR (i BINARY_INTEGER) RETURN BINARY_INTEGER; FUNCTION NEXT (i BINARY_INTEGER) RETURN BINARY_INTEGER; Example This function returns the sum of elements in a List_t collection of numbers: CREATE FUNCTION compute_sum (the_list IN List_t) RETURN NUMBER AS elt BINARY_INTEGER := the_list.FIRST; total NUMBER := 0; BEGIN LOOP EXIT WHEN elt IS NULL; total := total + the_list(elt); elt := the_list.NEXT(elt); END LOOP; RETURN total; END; Returns PRIOR returns the next lower index in use relative to i; NEXT returns the next higher. Applies to Nested tables, index-by tables, VARRAYs. Boundary considerations Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. If applied to initialized collections which have no elements, returns NULL. If i is greater than or equal to COUNT, NEXT returns NULL; if i is less than or equal to FIRST, PRIOR returns NULL. (Currently, if the collection has elements, and i is greater than COUNT, PRIOR returns LAST; if i is less than FIRST, NEXT returns FIRST; however, do not rely on this behavior in future Oracle versions.) Exceptions possible If applied to an uninitialized nested table or a VARRAY, raises COLLECTION_IS_NULL predefined exception. 19.6.8 TRIM [ (n ) ] Specification PROCEDURE TRIM (n BINARY_INTEGER:=1); Example CREATE FUNCTION pop (the_list IN OUT List_t) RETURN VARCHAR2 AS l_value VARCHAR2(30); BEGIN IF the_list.COUNT >= 1 THEN /* Save the value of the last element in the collection || so it can be returned */ l_value := the_list(the_list.LAST); the_list.TRIM; END IF; RETURN l_value; END; Action Removes n elements from the end of a collection. Without arguments, TRIM removes exactly one element. Confusing behavior occurs if you combine DELETE and TRIM actions on a collection; for example, if an element that you are trimming has previously been DELETEd, TRIM "repeats" the deletion but counts this as part of n, meaning that you may be TRIMming fewer actual elements than you think. Applies to Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Nested tables, VARRAYs. Attempting to TRIM an index-by table will produce a compile- time error. Boundary considerations If n is null, TRIM will do nothing. Exceptions possible Will raise SUBSCRIPT_BEYOND_COUNT if you attempt to TRIM more elements than actually exist. If applied to an uninitialized nested table or a VARRAY, raises COLLECTION_IS_NULL predefined exception. Previous: 19.5 Collection Pseudo-Functions OraclePL/SQL Programming, 2nd Edition Next: 19.7 Example: PL/ SQL-to-Server Integration 19.5 Collection Pseudo- Functions Book Index 19.7 Example: PL/SQL-to- Server Integration The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates. All rights reserved. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Previous: 19.6 Collection Built-Ins Chapter 19 Nested Tables and VARRAYs Next: 19.8 Collections Housekeeping 19.7 Example: PL/SQL-to-Server Integration To provide an(other) demonstration of how collections can ease the burden of transferring data between server and PL/SQL application program, let's look at a new example. The main entity in this example is the "apartment complex." We use a nested table of objects in order to hold the list of apartments for each apartment complex. Each apartment is described by the following attributes: CREATE TYPE Apartment_t AS OBJECT ( unit_no NUMBER, square_feet NUMBER, bedrooms NUMBER, bathrooms NUMBER, rent_in_dollars NUMBER ); And we can now define the nested table type which will hold a list of these apartment objects: CREATE TYPE Apartment_tab_t AS TABLE OF Apartment_t; Using this type as the type of a column, here is the definition of our database table: CREATE TABLE apartment_complexes (name VARCHAR2(75), landlord_name VARCHAR2(45), apartments Apartment_tab_t) NESTED TABLE apartments STORE AS apartments_store_tab; If you're curious, the INSERT statements to populate such a table look like the following (note the use of nested constructors to create the collection of objects): INSERT INTO apartment_complexes VALUES Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. ('RIVER OAKS FOUR', 'MR. JOHNSON', Apartment_tab_t( Apartment_t(1, 780, 2, 1, 975), Apartment_t(2, 1200, 3, 2, 1590), Apartment_t(3, 690, 1, 1.5, 800), Apartment_t(4, 690, 1, 2, 450), Apartment_t(5, 870, 2, 2, 990) ) ); INSERT INTO apartment_complexes VALUES ('GALLERIA PLACE', 'MS. DODENHOFF', Apartment_tab_t( Apartment_t(101, 1000, 3, 2, 1295), Apartment_t(102, 800, 2, 1, 995), Apartment_t(103, 800, 2, 1, 995), Apartment_t(201, 920, 3, 1.5, 1195), Apartment_t(202, 920, 3, 1.5, 1195), Apartment_t(205, 1000, 3, 2, 1295) ) ); Now, at last, we can show off some wonderful features of storing collections in the database. Imagine that we are the new managers of the River Oaks Four apartments (hardly large enough to qualify as a complex) and we want to demolish any unit that rents for less than $500, and raise the rent on everything else by 15%. DECLARE /* Declare the cursor that will retrieve the collection of || apartment objects. Since we know we're going to update the || record, we can lock it using FOR UPDATE. */ CURSOR aptcur IS SELECT apartments FROM apartment_complexes WHERE name = 'RIVER OAKS FOUR' FOR UPDATE OF apartments; /* Need a local variable to hold the collection of fetched || apartment objects. */ l_apartments apartment_tab_t; which INTEGER; Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. BEGIN /* A single fetch is all we need! */ OPEN aptcur; FETCH aptcur INTO l_apartments; CLOSE aptcur; /* Iterate over the apartment objects in the collection and || delete any elements of the nested table which meet the || criteria */ which := l_apartments.FIRST; LOOP EXIT WHEN which IS NULL; IF l_apartments(which).rent_in_dollars < 500 THEN l_apartments.DELETE(which); END IF; which := l_apartments.NEXT(which); END LOOP; /* Now iterate over the remaining apartments and raise the || rent. Notice that this code will skip any deleted || elements. */ which := l_apartments.FIRST; LOOP EXIT WHEN which IS NULL; l_apartments(which).rent_in_dollars := l_apartments(which).rent_in_dollars * 1.15; which := l_apartments.NEXT(which); END LOOP; /* Finally, ship the entire apartment collection back to the || server -- in a single statement! */ UPDATE apartment_complexes SET apartments = l_apartments WHERE name = 'RIVER OAKS FOUR'; END; Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. To me, one of the most significant aspects of this example is the single-statement fetch (and store). This PL/SQL fragment emulates the creating of a "client-side cache" of data, which is an essential concept in many object-oriented and client-server architectures. Using this kind of approach with collections can reduce network traffic and improve the quality of your code. Previous: 19.6 Collection Built-Ins OraclePL/SQL Programming, 2nd Edition Next: 19.8 Collections Housekeeping 19.6 Collection Built-Ins Book Index 19.8 Collections Housekeeping The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates. All rights reserved. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Previous: 19.7 Example: PL/SQL-to-Server Integration Chapter 19 Nested Tables and VARRAYs Next: 19.9 Which Collection Type Should I Use? 19.8 Collections Housekeeping Here are some not-so-obvious bits of information that will assist you in using nested tables and VARRAYS. 19.8.1 Privileges When they live in the database, collection datatypes can be shared by more than one Oracle user (schema). As you can imagine, privileges are involved. Fortunately, it's not complicated; only one Oracle privilege -- EXECUTE -- applies to collection types. If you are SCOTT and you want to grant JOE permission to use Color_tab_t in his programs, all you need to do is grant the EXECUTE privilege to him: GRANT EXECUTE on Color_tab_t TO JOE; Joe can then refer to the type using schema.type notation. For example: CREATE TABLE my_stuff_to_paint ( which_stuff VARCHAR2(512), paint_mixture SCOTT.Color_tab_t ); EXECUTE privileges are also required by users who need to run PL/SQL anonymous blocks that uses the object type. That's one of several reasons that named PL/SQL modules -- packages, procedures, functions -- are generally preferred. Granting EXECUTE on the module confers the grantor's privileges to the grantee while executing the module. For tables that include collection columns, the traditional SELECT, INSERT, UDPATE, and DELETE privileges still have meaning, as long as there is no requirement to build a collection for any columns. However, if a user is going to INSERT or UPDATE the contents of a collection column, the user must have the EXECUTE privilege on the type, because that is the only way to use the default constructor. 19.8.2 Data Dictionary Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. There are a few new entries in the data dictionary (shown in Table 19.3) that will be very helpful in managing your collection types. The shorthand dictionary term for user-defined types is simply TYPE. Collection type definitions are found in the USER_SOURCE view (or DBA_SOURCE, or ALL_SOURCE). Table 19.3: Data Dictionary Entries for Collection Types To Answer the Question . Use This View As In What collection types have I created? USER_TYPES SELECT type_name FROM user_types WHERE type_code = 'COLLECTION'; What was the original type definition of collection Foo_t? USER_SOURCE SELECT text FROM user_source WHERE name = 'FOO_T' AND type = 'TYPE' ORDER BY line; What columns implement Foo_t? USER_TAB_COLUMNS SELECT table_name, column_name FROM user_tab_columns WHERE data_type = 'FOO_T'; What database objects are dependent on Foo_t? USER_DEPENDENCIES SELECT name, type FROM user_dependencies WHERE referenced_name = 'FOO_T'; 19.8.3 Call by Reference or Call by Value Under certain circumstances that are beyond the control of the programmer, PL/SQL will pass collection arguments by reference rather than by value. The rationale is that since collections can be large, it is more efficient to pass only a pointer (call by reference) than to make a copy of the collection (call by value). Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... most PL/SQL programs If you are in the habit of using "in line" module definitions, it's probably not a good idea to rely on the value of global variables anyway! Previous: 19.7 Example: PL/SQL- to-Server Integration 19.7 Example: PL/SQL- toServer Integration OraclePL/SQL Programming, 2nd Edition Book Index Next: 19.9 Which Collection Type Should I Use? 19.9 Which Collection Type Should I Use? The Oracle. .. For example, even Oracle Version 6 allowed updates through a view of a single table which uses no aggregation clauses such as GROUP BY While Oracle7 added to the family of modifiable views, even in Oracle8 there is still a class of views which are "inherently unmodifiable" if you limit yourself to standard SQL However, in Oracle8 , if you can come up with the logic of how you want Oracle to interpret... every Oracle feature at your application Use a feature if it make sense for your architectural approach I tend to agree with Oracle' s advice that if you do use triggers, you should use them in moderation Previous: 20.1 Example: Using Object Views 20.1 Example: Using Object Views OraclePL/SQL Programming, 2nd Edition Book Index Next: 20.3 Syntax for Object Views 20.3 Syntax for Object Views The Oracle. .. discussion of PL/SQL- specific aspects of object views is rather terse, for two reasons: Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 1 Object views are substantially similar to regular object types, which are covered in a Chapter 18 2 As a topic, object views are closer to SQL than to PL/SQL However, PL/SQL developers who are interested in fully exploiting Oracle' s object... methods and/or PL/SQL packages (discussed in-depth in Chapter 18) Write INSTEAD OF triggers that will allow direct manipulation of the view's contents (discussed in the next section) Previous: 19.9 Which Collection Type Should I Use? 19.9 Which Collection Type Should I Use? OraclePL/SQL Programming, 2nd Edition Next: 20.2 INSTEAD OF Triggers Book Index 20.2 INSTEAD OF Triggers The Oracle Library Navigation... simultaneously If you need sparse PL/SQL tables, say, for "data-smart" storage, your only practical option is an index-by table True, you could allocate and then delete elements of a nested table variable as illustrated in the section on NEXT and PRIOR methods, but it is inefficient to do so for anything but the smallest collections If your PL/SQL program needs to run under both Oracle7 and Oracle8 , you also have... type of trigger is available to all Oracle8 users; it is not a part of the Oracle objects option Conceptually, INSTEAD OF triggers are very simple You write code that the Oracle server will execute when a program performs a DML operation on the view Unlike a conventional BEFORE or AFTER trigger, an INSTEAD OF trigger takes the place of, rather than supplements, Oracle' s usual DML behavior (And in case... Oracle7 and Oracle8 , you also have only one option: index-by tables Or, if your PL/SQL application requires negative subscripts, you also have to use index-by tables Previous: 19.8 Collections Housekeeping 19.8 Collections Housekeeping OraclePL/SQL Programming, 2nd Edition Book Index Next: 20 Object Views 20 Object Views The Oracle Library Navigation Please purchase PDF Split-Merge on www.verypdf.com... Postscript: Using the BFILE Datatype Although Oracle' s object extensions offer rich possibilities for the design of new systems, few Oracle shops with large relational databases in place will want to, or be able to, completely reengineer those systems to use objects To allow established applications to take advantage of the new object features over time, Oracle8 provides object views With object views,... least in Oracle 8.0.3 This behavior is a suspected bug Previous: 20.2 INSTEAD OF Triggers 20.2 INSTEAD OF Triggers OraclePL/SQL Programming, 2nd Edition Book Index Next: 20.4 Differences Between Object Views and Object Tables 20.4 Differences Between Object Views and Object Tables The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates All rights reserved Please purchase PDF Split-Merge . 19.7 Example: PL/SQL- to-Server Integration Oracle PL/SQL Programming, 2nd Edition Next: 19.9 Which Collection Type Should I Use? 19.7 Example: PL/SQL- to-. collections. ● If your PL/SQL program needs to run under both Oracle7 and Oracle8 , you also have only one option: index-by tables. Or, if your PL/SQL application