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

Tài liệu Oracle PL/SQL Language Pocket Reference- P22 pptx

50 352 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Tiêu đề Tài liệu Oracle PL/SQL Language Pocket Reference- P22 pptx
Trường học O'Reilly & Associates
Chuyên ngành Oracle PL/SQL Programming
Thể loại Pocket Reference
Năm xuất bản 2000
Định dạng
Số trang 50
Dung lượng 203,6 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 1

FUNCTION 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 2

The 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 3

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.)

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 4

Nested 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 5

Previous: 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 7

SET apartments = l_apartments

WHERE name = 'RIVER OAKS FOUR';

END;

Trang 8

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

Oracle PL/SQL Programming, 2nd Edition

Next: 19.8 Collections Housekeeping

19.6 Collection Built-Ins Book Index 19.8 Collections

Trang 9

Previous: 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 10

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

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 11

Usually, 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 12

Previous: 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 13

Copyright (c) 2000 O'Reilly & Associates All rights reserved

Trang 14

Syntax 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 15

Legacy 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 16

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 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 17

keywords 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 18

I'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 19

OK, 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 21

Previous: 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 22

IF :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 23

20.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 24

Ability 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

Ngày đăng: 15/12/2013, 04:15

TỪ KHÓA LIÊN QUAN