Each apartment is described by the following attributes: CREATE TYPE Apartment_t AS OBJECT And we can now define the nested table type which will hold a list of these apartment objects:
Trang 1FUNCTION LAST RETURN BINARY_INTEGER;
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
Trang 2The maximum number of elements that is possible for a given VARRAY.
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
EXIT WHEN elt IS NULL;
total := total + the_list(elt);
Trang 3If 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.)
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
Trang 4Nested tables, VARRAYs Attempting to TRIM an index-by table will produce a time error
Next: 19.7 Example: PL/
SQL-to-Server Integration19.5 Collection Pseudo-
Trang 5Previous: 19.6 Collection
Built-Ins
Chapter 19Nested 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 (
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
Trang 6('RIVER OAKS FOUR', 'MR JOHNSON',
INSERT INTO apartment_complexes VALUES
('GALLERIA PLACE', 'MS DODENHOFF',
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%
WHERE name = 'RIVER OAKS FOUR'
FOR UPDATE OF apartments;
/* Need a local variable to hold the collection of
Trang 7SET apartments = l_apartments
WHERE name = 'RIVER OAKS FOUR';
END;
Trang 8To 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
Oracle PL/SQL Programming, 2nd Edition
Next: 19.8 Collections Housekeeping
19.6 Collection Built-Ins Book Index 19.8 Collections
Trang 9Previous: 19.7 Example:
PL/SQL-to-Server
Integration
Chapter 19Nested 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 (
19.8.2 Data Dictionary
Trang 10There 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
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)
Trang 11Usually, the compiler's choice of parameter passing approach is invisible to the application programmer
Not knowing whether the compiler will pass arguments by reference or by value can lead to unexpected results if all of the following conditions are met:
1 You have created a procedure or function "in line" in another module's declaration section (these are known as nested or local program units and are explained in Chapter 15, Procedures and
Functions)
2 The inline module refers to a "global" collection variable declared outside its definition
3 In the body of the outer module, this collection variable is passed as an actual parameter to the inline module
This is a rather uncommon combination of affairs in 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
Oracle PL/SQL Programming, 2nd Edition
Next: 19.9 Which Collection Type Should I Use?
Trang 12Previous: 19.8 Collections
Housekeeping
Chapter 19Nested Tables and VARRAYs
Next: 20 Object Views
19.9 Which Collection Type Should I Use?
It's not altogether obvious how to choose the best type of collection for a given application Here are some guidelines:
● If you intend to store large amounts of persistent data in a column collection, your only option
is a nested table Oracle will then use a separate table behind the scenes to hold the collection data, so you can allow for almost limitless growth
● If you want to preserve the order of elements that get stored in the collection column and your dataset will be "small," use a VARRAY What is "small?" I tend to think in terms of how much data you can fit into a single database block; if you span blocks, you get row chaining, which decreases performance The database block size is established at database creation time and is typically 2K, 4K, or 8K
● Here are some other indications that a VARRAY would be appropriate: you don't want to worry about deletions occurring in the middle of the dataset; your data has an intrinsic upper bound; or you expect, in general, to retrieve the entire collection 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 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
Oracle PL/SQL Programming, 2nd Edition
Next: 20 Object Views
19.8 Collections
Housekeeping
Book Index 20 Object Views
The Oracle Library
Navigation
Trang 13Copyright (c) 2000 O'Reilly & Associates All rights reserved
Trang 14Syntax for Object Views
Differences Between Object Views and Object Tables
Not All Views with Objects Are Object Views
Schema Evolution
Object Views Housekeeping
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, you can achieve the following benefits:
● Efficiency of object access In PL/SQL, and particularly in Oracle Call Interface (OCI)
applications, object programming constructs provide for the convenient retrieval, caching, and updating of object data These programming facilities provide performance improvements, with the added benefit that application code can now be more succinct
● Ability to navigate using REFs (reference pointers) By designating unique identifiers as the
basis of an object identifier (OID), you can reap the benefits of object navigation For
example, you can retrieve attributes from related "virtual objects" using dot notation rather than via explicit joins
● Easier schema evolution In early versions of Oracle8, a pure object approach renders almost
any kind of schema change at best ugly (see Chapter 18, Object Types) In contrast, object views offer more ways that you can change both the table structure and the object type
definitions of an existing system
● Consistency with new object-based applications If you need to extend the design of a legacy
database, the new components can be implemented in object tables; new object-oriented
applications requiring access to existing data can employ a consistent programming model
Trang 15Legacy applications can continue to work without modification
Other new features of Oracle can improve the expressiveness of any type of view, not just object views Two features which are not strictly limited to object views are collections and "INSTEAD OF" triggers Consider two relational tables with a simple master-detail relationship Using the Oracle objects option, you can portray the detail records as a single nonscalar attribute (collection) of the master, which could be a very useful abstraction In addition, by using INSTEAD OF triggers, you can tell Oracle exactly how to perform inserts, updates, and deletes on any view These two features are available to both object views and nonobject views (I've described collections in Chapter 19,
Nested Tables and VARRAYs, and I describe INSTEAD OF triggers later in this chapter.)
From an object-oriented perspective, there is one unavoidable "disadvantage" of object views, when compared to reengineering using an all-object approach: object views cannot retrofit any benefits of encapsulation Insofar as old applications apply INSERT, UPDATE, and DELETE statements
directly to table data, they will subvert the benefits of encapsulation normally provided by an object approach As I discussed in Chapter 18, object-oriented designs typically prevent free-form access directly to object data
Despite this intrusion of reality, if you do choose to layer object views on top of a legacy system, your future applications can employ object abstractions and enjoy many benefits of encapsulation and
information hiding And your legacy systems are no worse off than they were before! Figure 20.1illustrates this use of object views
Figure 20.1: Object views allow you to "bind" an object type definition to (existing) relational tables
This chapter discusses the nuances of creating and, to a lesser extent, using object views The
discussion of PL/SQL-specific aspects of object views is rather terse, for two reasons:
Trang 161 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 features must understand object views This chapter pays close attention to the areas of difference between object tables and object views
20.1 Example: Using Object Views
In our first example, let's look at how object views might be used at Planetary Pages, a fictitious firm that designs Web sites Their existing relational application tracks JPEG, GIF, and other images that they use when designing client Web sites These images are stored in files, but data about them are stored in relational tables To help the graphic artists locate the right image, each image has one or more associated keywords, stored in a straightforward master-detail relationship
Our legacy system has one table for image metadata:
CREATE TABLE images (
image_id INTEGER NOT NULL,
file_name VARCHAR2(512),
file_type VARCHAR2(12),
bytes INTEGER,
CONSTRAINT image_pk PRIMARY KEY (image_id));
and one table for the keywords associated with the images:
CREATE TABLE keywords (
image_id INTEGER NOT NULL,
keyword VARCHAR2(45) NOT NULL,
CONSTRAINT keywords_pk PRIMARY KEY (image_id, keyword),
CONSTRAINT keywords_for_image FOREIGN KEY (image_id)
REFERENCES images (image_id));
To create a more useful abstraction, Planetary Pages has decided to logically merge these two tables into a single object view To do so, we must first create an object type with appropriate attributes Since there are usually only a few keywords for a given image, this relationship lends itself to using
an Oracle collection to hold the keywords
Before we can create the top-level type, we must first define a collection to hold the keywords We choose a nested table because keyword ordering is unimportant and because there is no logical
maximum number of keywords.[1]
[1] If ordering were important, or if there were a (small) logical maximum number of
Trang 17keywords per image, a VARRAY collection would be a better choice See Chapter 19
for details
CREATE TYPE Keyword_tab_t AS TABLE OF VARCHAR2(45);
From here, it's a simple matter to define the object type To keep the example short, we'll define only
a couple of methods In the following object type specification, notice that the keywords attribute is defined on the Keyword_tab_t collection type:
CREATE TYPE Image_t AS OBJECT (
MEMBER FUNCTION set_attrs (new_file_name IN VARCHAR2,
new_file_type IN VARCHAR2, new_bytes IN INTEGER)
Here is the body:
CREATE TYPE BODY Image_t
AS
MEMBER FUNCTION set_attrs (new_file_name IN VARCHAR2,
new_file_type IN VARCHAR2, new_bytes IN INTEGER)
Trang 18I've presented the body only for completeness; from this point forward, I'll discuss object views
without regard for the details of their underlying type bodies
At this point, there is no connection between the relational tables and the object type They are
independent organisms It is when we build the object view that we "overlay" the object definition onto the tables
Finally, to create the object view, we use the following statement:
CREATE VIEW images_v
OF Image_t
WITH OBJECT OID (image_id)
AS
SELECT i.image_id, i.file_name, i.file_type, i.bytes,
CAST (MULTISET (SELECT keyword
This means that the view will return objects of type Image_t
WITH OBJECT OID (image_id)
To behave like a "real" object instance, data returned by the view will need some kind of object identifier By designating the primary key as the basis of a virtual OID, we can enjoy the benefits of referencing objects of this type from other object views
In addition, the select-list has an important requirement unique to object views The select-list must define the same number of columns as there are attributes in the object type Image_t The datatype of each retrieved column matches the datatype of its corresponding object attributes
You can use the CAST clause shown in the example in any view, not just in object views (but it does require the presence of the Oracle objects option) This subquery performs an "on-the-fly" conversion
of the detail records into a collection type For more details about the CAST and MULTISET
operators, refer to Section 19.5, "Collection Pseudo-Functions" in Chapter 19
Trang 19OK, now that we've created it, what can we do with it? Well, we can retrieve data from it just as if it were an object table First, let's put some data into the underlying tables:
INSERT INTO images VALUES (100001, 'smiley_face.gif',
'GIF', 813);
INSERT INTO images VALUES (100002, 'peace_symbol.gif',
'GIF', 972);
INSERT INTO KEYWORDS VALUES (100001, 'SIXTIES');
INSERT INTO KEYWORDS VALUES (100001, 'HAPPY FACE');
INSERT INTO KEYWORDS VALUES (100002, 'SIXTIES');
INSERT INTO KEYWORDS VALUES (100002, 'PEACE SYMBOL');
INSERT INTO KEYWORDS VALUES (100002, 'JERRY RUBIN');
Now, from SQL*Plus, you can make a query like the following:
SELECT image_id, file_name, keywords
100002 peace_symbol.gif KEYWORD_TAB_T('JERRY RUBIN',
'PEACE SYMBOL', 'SIXTIES')
Or, in a PL/SQL block, we can fetch and display a row of data very easily:
SET SERVEROUTPUT ON SIZE 100000
Trang 20/* Print it out, just to prove that we got it */
Keywords: HAPPY FACE SIXTIES
See Chapter 19 for more examples of retrieving data from an object table
Other things you can do with object views include the following:
● Define REFs that point to "virtual" objects (discussed in detail in Section 20.4, "Differences Between Object Views and Object Tables" later in this chapter)
● Encapsulate an object view (more or less) using 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?
Oracle PL/SQL Programming, 2nd Edition
Next: 20.2 INSTEAD OF Triggers
19.9 Which Collection Type
Should I Use?
Book Index 20.2 INSTEAD OF Triggers
The Oracle Library
Navigation
Copyright (c) 2000 O'Reilly & Associates All rights reserved
Trang 21Previous: 20.1 Example:
Using Object Views
Chapter 20Object Views
Next: 20.3 Syntax for Object Views
20.2 INSTEAD OF Triggers
Some conventional views are "inherently modifiable." 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 a
particular operation on a view however wacky that view might be you can implement the
behavior with INSTEAD OF triggers Happily, this new 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 you're wondering, you cannot use BEFORE/AFTER triggers on any type of view, even if you have defined an INSTEAD OF trigger on the view.)
For example, to allow applications to INSERT into our images_v view, we could write the following trigger:
CREATE OR REPLACE TRIGGER images_v_insert
INSTEAD OF INSERT ON images_v
FOR EACH ROW
INSERT INTO images
VALUES (:NEW.image_id, :NEW.file_name, :NEW
file_type,
:NEW.bytes);
Trang 22IF :NEW.keywords IS NOT NULL THEN
INSERT INTO keywords
VALUES (:NEW.image_id, keywords_holder
Once we've created this INSTEAD OF trigger, we can insert a record into this object view (and hence
into both underlying tables) quite easily using:
INSERT INTO images_v
VALUES (Image_t(41265, 'pigpic.jpg', 'JPG', 824,
Keyword_tab_t('PIG', 'BOVINE', 'FARM ANIMAL')));
This statement causes the INSTEAD OF trigger to fire, and as long as the primary key value
(image_id = 41265) does not already exist, the trigger will insert the data into the appropriate tables
Similarly, we can write additional triggers that handle updates and deletes These triggers use the predictable clauses INSTEAD OF UPDATE and INSTEAD OF DELETE
20.2.1 INSTEAD OF Triggers: To Use or Not to Use?
Before launching headlong into the business of updating complex views with triggers, let's step back
and look at the bigger picture Do we really want to use INSTEAD OF triggers in an Oracle
environment? Particularly if we are migrating toward an object approach, isn't this new feature just a relational "throwback" which facilitates a free-for-all in which any application can perform DML? Yes and no
Let's consider arguments on both sides, and come up with some considerations so you can decide what's best for your application
Trang 2320.2.1.1 The "don't use" argument
On the one hand, you could use tools such as packages and methods to provide a more
comprehensive technique than triggers for encapsulating DML It is nearly trivial to take the logic from our INSTEAD OF trigger and put it into an alternate PL/SQL construct which has more
universal application In other words, if you standardize on some combination of packages and object methods as the means of performing DML, you could keep your environment consistent without using view triggers You might conclude that view triggers are just another variable in an
increasingly complex standards equation
Moreover, even Oracle cautions against the "excessive use" of triggers, because they can cause
"complex interdependencies." Imagine if your INSTEAD OF triggers performed DML on tables which had other triggers, which performed DML on still other tables it's easy to see how this could get confusing
20.2.1.2 The "use" argument
On the other hand, you can put much of the necessary logic into an INSTEAD OF trigger that you would normally put into a package or method body Doing so in combination with a proper set of privilege restrictions could protect your data just as well as, or even better than, methods or packages
What's more, if you use a client tool such as Oracle Forms, INSTEAD OF triggers allow you to use much more of the product's default functionality when you create a Forms "block" against a view rather than a table This fact alone could make object views wildly popular
Finally, if you use OCI, a more significant factor is that INSTEAD OF triggers are required if the
object view is not inherently modifiable and you want to be able to easily "flush" cached object view data back to the server
Table 20.1: Assessment of Techniques for Encapsulating DML on Object ViewsDML Consideration PL/SQL Package Object Method INSTEAD OF Trigger
Trang 24Ability to adapt to schema
changes
Excellent; can be easily altered and recompiled
independently
Poor, especially if object types are responsible for their own persistence
Good, but still some areas where Oracle does not
automatically recompile dependent structures
Risk of unexpected
interactions
have unpredictable interactions with each other
Ease of use with client tool
Acceptable;
programmer must add code for all client-side transactional triggers
Excellent (however, there is no INSTEAD
OF LOCK side trigger)
server-Ability to use technique on
transient objects
Very good, but not a
"natural" use of packages
enabling the trigger)
Chapter 18 discussed at some length architectural considerations of packages versus methods While those considerations also apply to object views, we now need to compare packages and methods with INSTEAD OF triggers
As you can see, there is no clear "winner." Each technique has benefits that may be of more or less importance to your own particular application
And of course, you may decide that INSTEAD OF triggers make sense in combination with PL/SQL
packages and/or object methods to provide layers of encapsulation For example:
CREATE OR REPLACE TRIGGER images_v_insert
INSTEAD OF INSERT ON images_v
FOR EACH ROW
BEGIN
/* Call a packaged procedure to perform the insertion
Trang 25|| (The called procedure is not presented in the text.) */
Previous: 20.1 Example:
Using Object Views
Oracle PL/SQL Programming, 2nd Edition
Next: 20.3 Syntax for Object Views
20.1 Example: Using Object
Views
Book Index 20.3 Syntax for Object Views
The Oracle Library
Navigation
Copyright (c) 2000 O'Reilly & Associates All rights reserved