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

Tài liệu Oracle PL/SQL Language Pocket Reference- P20 pdf

50 446 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 đề Oracle PL/SQL Language Pocket Reference - P20
Trường học O'Reilly & Associates
Chuyên ngành Database Programming / Oracle PL/SQL
Thể loại Pocket Reference
Năm xuất bản 2000
Định dạng
Số trang 50
Dung lượng 177,98 KB

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

Nội dung

Previous: 18.2 Oracle Objects Example Chapter 18Object Types Next: 18.4 Manipulating Objects in PL/SQL and SQL 18.3 Syntax for Creating Object Types This section explains the syntax for

Trang 1

CREATE TABLE pets OF Pet_t

(PRIMARY KEY (tag_no))

NESTED TABLE vaccinations STORE AS

pet_vaccinations_tab;

Using this separate persons table and the REF attribute will allow the existence of people outside the context of their pets (something the pet-obsessed may not envision, but probably a good idea from a

design point of view) In this context, REF is called a type modifier

Does a REF sound a lot like a foreign key? While there are important differences between REFs and foreign keys (see Table 18.2), Oracle actually claims that REFs, are "more reliable and persistent" than foreign keys probably because REFs do not refer to user-changeable values, but rather to invisible internal values

In fact, the problem with REFs is that they are too persistent Oracle currently allows you to delete an

object that is the target of a REF without deleting the reference to it They even dignify this state with

a name: a dangling REF This is roughly equivalent to what would happen if you delete a department

record without changing the records of employees in that department There is no declarative way to prevent dangling REFs, but it should not be too challenging to do so by implementing pre-delete triggers on the table that contains the "parent" objects.[11] To make life somewhat easier, Oracle provides a predicate, IS DANGLING, to test for this condition:

[11] It is also possible to use a foreign key in combination with a REF To do so, you

would include an attribute for the foreign key in the Pet_t specification and include a

FOREIGN KEY clause in the CREATE TABLE statement

UPDATE pets

SET owner_ref = NULL

WHERE owner_ref IS DANGLING;

Table 18.2: Chief Differences between Foreign Keys and REFs

Who defines the value used as the

"pointer?"

User (programmer) System

Requirements on the parent Must have primary or unique

key

Must be an object table or object view

Trang 2

Only allows insertions of child if

parent exists (or if the referencing

columns are null)?

Yes, when enabled Yes, since you can only

insert a "real" REF

Can be defined in such a way that

the child may be associated with

one of several possible parents?

No (although foreign keys have

a little-known ability to point to

all of several possible parents)

Yes; by default, a REF can refer to any row object of the given type

Can declaratively restrict the scope

of the child so that it can point to

only one given parent table?

No Yes (by using the SCOPE

clause in the CREATE TABLE command)

Restricts updates of the parent key

when children exist?

Yes Yes; object identifiers are

Default type of relationship

between parent and child when

NOTE: In Table 18.2, we use the terminology "parent" and "child" only for

convenience; these terms are not always accurate descriptions of objects linked via

Trang 3

Previous: 18.1 Introduction

to Oracle8 Objects

Oracle PL/SQL Programming, 2nd Edition

Next: 18.3 Syntax for Creating Object Types18.1 Introduction to Oracle8

Trang 4

Previous: 18.2 Oracle

Objects Example

Chapter 18Object Types

Next: 18.4 Manipulating Objects in PL/SQL and SQL

18.3 Syntax for Creating Object Types

This section explains the syntax for CREATE TYPE, CREATE TYPE BODY, and some of the other statements you will use when working with Oracle objects

18.3.1 About Object Types

A given object type can have all of the following:

● One default constructor method

● Zero or one comparison methods

● Any number of member methods

The default constructor, supplied automatically when you create an object type, allows you to create

an object of the corresponding type You have no direct control over this function (aside from how you have defined the attributes of the object type) The constructor is the only type of method that does not operate on an existing object

Comparison methods are either MAP or ORDER methods (see Section 18.3.6, "Comparing Objects"later in this chapter) They allow you to establish rules so that SQL statements and PL/SQL programs can order, group, and otherwise compare object instances Comparison methods are always functions

Member methods are either member functions or member procedures These are where programmers define the bulk of the object's behavior

18.3.2 CREATE TYPE and DROP TYPE: Creating and Dropping Types

The CREATE TYPE statement has the following general format:

CREATE [ OR REPLACE ] TYPE <type name> AS OBJECT

<attribute name> datatype, ,

MEMBER PROCEDURE | FUNCTION <procedure or function

Trang 5

As you would expect, you can drop a type using a DROP statement as follows:

DROP TYPE <type name> [ FORCE ] ;

Parameters have the following meanings:

OR REPLACE

Tells Oracle that you want to rebuild the type if it should happen to already exist This will preserve grants (See "Schema Evolution" later in the chapter for information about the effect this option has on the object type's metadata.)

type name

A legal Oracle identifier that isn't already in use by any other Oracle database object such as another type, table, or package May be expressed in "schema dot" notation (e.g., SCOTT.foo)

attribute name

A legal PL/SQL identifier for the attribute

datatype

Any legal Oracle datatype except LONG, LONG RAW, NCHAR, NCLOB, NVARCHAR2,

ROWID, BINARY_INTEGER, BOOLEAN, PLS_INTEGER, RECORD, REF CURSOR, %TYPE, %ROWTYPE, or types that exist only within packages

comparison function

Defines a function that allows comparison of object values

what to restrict

This is either the name of the function or procedure, or the keyword DEFAULT Using

DEFAULT tells Oracle that all member functions and procedures in the object type will have

the designated restrictions, without having to list each one in its own

RESTRICT_REFERENCES pragma

restrictions

One or more of the following: RNDS, WNDS, RNPS, and WNPS (see Chapter 17)

FORCE++

Trang 6

Tells Oracle that you want to drop a type even if there are other objects with dependencies on

it Even if you use FORCE, you can only drop a type if it has not been implemented in a table; you must first drop the table(s) before dropping the type

Notice that the syntax for creating the specification is merely a comma-separated list of attributes and methods There are no semicolons as you would find in a package specification

You cannot impose NOT NULL or DEFAULT constraints at the attribute level These constraints can, however, be applied to scalar attributes if you create an object table based on type The syntax is:

CREATE TABLE <table name> OF <object type name>

(<column constraint>, );

For example:

CREATE TABLE foos OF Foo_t

(bar NOT NULL);

or, if you wish to name a constraint:

CREATE TABLE foos OF Foo_t

(CONSTRAINT bar_not_null CHECK (bar IS NOT NULL));

18.3.3 CREATE TYPE BODY: Creating a Body

The syntax for the CREATE TYPE BODY statement is the following:

CREATE [ OR REPLACE ] TYPE BODY <type name> AS | IS (

MEMBER PROCEDURE | FUNCTION <procedure or function

Trang 7

basil.meals.calories@mktg.ny.acme.com In PL/SQL Version 2 and up, dots are found in record datatypes, table datatype operators, packaged procedure or function references, and elsewhere

In the objects option, there are at least two new opportunities to get confused with dots: object data structures and object methods (And the discussion below ignores the fact that object names can be preceded by the schema name, as in schema_name.object_name.)

18.3.4.1 Dots in data structures

In a PL/SQL program, you can refer to object attributes with dot notation, as in object_name

attribute_name For example, after declaring and initializing an object my_pet of type Pet_t, we can

do this:

IF my_pet.sex = 'M' THEN

This variable means "the sex attribute of the object instance my_pet."

Referring to nested objects in PL/SQL using dot notation is almost intuitive, as long as you're using embedded objects (that is, the attribute is an object itself, not a REF to an object)

CREATE OBJECT Pet_t (

The IF test above simply checks whether the first name of the owner of the Dalmatian is Persephone

In SQL statements, you can also use dots to navigate the components of nested objects Even when you have nested objects with REFs, SQL graciously allows you to navigate to the referenced object without actually doing a join:

CREATE OBJECT Pet_t (

owner_ref REF Person_t,

.);

CREATE TABLE pets of Pet_t;

SELECT name, p.owner_ref.first_name

Trang 8

FROM pets p;

That's a pretty neat trick No ugly join clause, just an intuitive "do the right thing" call It works for attributes and member functions that are defined with the appropriate RESTRICT_REFERENCES pragma But what do we do in PL/SQL? Is this legal?

in package called UTL_REF that supports navigation in PL/SQL

18.3.4.2 Dots in method invocations

When you invoke an object's member function or procedure, the dot syntax is straightforward, as in the following:

object_instance_name.function_name (args)

object_instance_name.procedure_name (args)

If you want to use the output from one method as the input to another, you don't have to use a

temporary variable You can actually chain methods together with dots, as long as they are type compatible:

object_name.function_name(args).function_name(args)

procedure_name(args)

Before we can take a look at an example that chains our Pet_t methods, we'll want to change the specification of print_me Instead of using the default IN OUT mode of the SELF parameter in a member procedure, we are going to make it an IN That is, instead of:

MEMBER PROCEDURE print_me

we want to use:

MEMBER PROCEDURE print_me (SELF IN Pet_t)

Trang 9

(Remember that we have to make this change in both the object type specification and the object type body.)

Why did we make the change? The default IN OUT mode can only accept a SELF parameter that is writeable, and function return values are never writeable But as an IN-only parameter, SELF can now accept a Pet_t object that is returned from one of the other functions

Here are some rules about chaining:

● Methods are invoked in order from left to right

● The return value of a chained method must be of the object type expected by the method to its right

● A chained call can include at most a single procedure

● If your chained call includes a procedure, it must be the right-most method in the chain

● Be sure that you don't try to use a function's return value (which is read-only) as an IN OUT input to the next method in the chain

18.3.4.3 Attribute or method?

In PL/SQL, there is no automatic visual distinction between an object attribute and an object method unless the method has arguments That is, in this code fragment:

IF my_pet.whatever = 'a value' THEN

we can't immediately determine if "whatever" is an attribute or a method! In some cases, this

ambiguity could be a feature, since one day we might want to replace an attribute by a method of the same name

If we want to make our code less mysterious, we can add a trailing empty parameter list to method calls which have no parameters, as in the following:

Trang 10

The empty parentheses notation works for both member functions and member procedures

NOTE: The situation is different in SQL statements If you call a member function

without parameters in a SQL statement, you must use empty parentheses notation That

is, if somefun is a function, don't do this:

SELECT p.somefun FROM pets p; invalid

The statement above fails with an ORA-00904, "invalid column name." The correct

syntax is:

SELECT p.somefun() FROM pets p;

18.3.5 SELF: The Implied Parameter

Because a method can only be called within the context of a particular object instance, it always has

an object of the corresponding type as a "parameter." This makes sense because the method will (almost) always need access to that object's attributes This implied parameter is called SELF By default, SELF is an IN parameter in member functions, and an IN OUT parameter in member

procedures

If we create an object to hold American Kennel Club papers:

CREATE TYPE Akc_paper_t AS OBJECT(

pet_ref REF Pet_t,

issued_on DATE,

contents BLOB);

the following member function specifications are equivalent:

MEMBER FUNCTION print_me RETURN BOOLEAN;

MEMBER FUNCTION print_me (SELF Akc_paper_t) RETURN

Trang 11

MEMBER PROCEDURE reissue (SELF Akc_paper_t);

MEMBER PROCEDURE reissue (SELF IN OUT Akc_paper_t);

Within the object type body, you can refer to the SELF object explicitly; if you do not, PL/SQL name resolution rules will attempt to "do the right thing" with attribute references In the example below, the name and issued_on attributes will resolve to attribute values even without the SELF parameter:

CREATE TYPE BODY Akc_paper_t

NOTE: Including SELF explicitly can improve program clarity.

18.3.5.1 Forward type definitions

What would you do if you wanted to define object types that depend on each other? Suppose that we want to implement the following relationships:

● Each pet has an owner of type Person_t; owners can have one or more pets

A person can have one and only one favorite pet.

The solution is a forward type definition, similar to forward declarations in PL/SQL packages (see

Chapter 16) A forward definition allows you to declare your intention to create a type before you actually define it:

/* Here is the incomplete type definition */

CREATE TYPE Person_t;

/* Now owner_ref can make a "forward" reference to the

|| Person_t type

*/

CREATE TYPE Pet_t AS OBJECT (

Trang 12

tag_no INTEGER,

owner_ref REF Person_t,

.the rest of the attributes and methods

CREATE TYPE organization_unit_t AS OBJECT (

id NUMBER,

parent REF organization_unit_t

works fine without forward type def

);

18.3.6 Comparing Objects

In the "old days," when Oracle offered only scalar datatypes, the semantics for comparing values were clearly defined For example, columns of type NUMBER are easily compared, ordered, and grouped Ditto for dates, and even character types, despite differences in national language sorting conventions NULLs have always given us some grief, but we can't argue that the rules about them were vague Things got a little more interesting in PL/SQL programs, because there we can have complex data structures such as records and table datatypes, which offer very few comparison features within the language

Now, if we are taking an object-oriented approach, it would be useful if Oracle allowed statements such as the following:

IF my_pet > your_pet THEN my_pet and your_pet are

objects

SELECT FROM pets ORDER BY owner; owner is an

object column

But it is not at all obvious how Oracle would deal with statements like these Should it do some sort

of "munching" average on the objects' attributes, or what?

Trang 13

In fact, Oracle allows us to formulate our own comparison rules for the object types we create By defining a special MAP or ORDER member function when we define an object type, we can tell Oracle how to compare objects of that type in both PL/SQL and SQL expressions

18.3.6.1 The MAP and ORDER methods

Let's say that we have created an object type Appointment_t that will help us in scheduling visits to the veterinary offices of Relative Pets We might need an application to compare appointments:

DECLARE

my_appointment Appointment_t;

your_appointment Appointment_t;

BEGIN

.initialize the appointments

IF my_appointment > your_appointment THEN

To perform this greater-than comparison, you'll need to define either a MAP or an ORDER function MAP and ORDER methods are mutually exclusive; a given object type may have exactly one MAP method, or exactly one ORDER method (or zero comparison methods of either type)

18.3.6.1.1 MAP member functions

The MAP method simply translates or "maps" each object into a scalar datatype space that Oracle knows how to compare For example, suppose we had a simple rule that says appointments are

"greater than" others if they occur later in time Then the MAP method is trivial:

CREATE TYPE Appointment_t AS OBJECT (

pet REF Pet_t,

scheduled_date DATE,

with_whom REF Doctor_t,

MAP MEMBER FUNCTION compare RETURN DATE

MAP functions accept no parameters and must return a date, character, or number that is,

something that SQL and PL/SQL already know how to compare

Trang 14

18.3.6.1.2

ORDER member functions

The alternative to MAP is an ORDER member function, which accepts two objects: SELF and another object of the same type You must program the ORDER member function to return an INTEGER that is one of the values -1, 0, or 1, indicating the ordering relationship of the second object to SELF That is, if you want:

● SELF < second object, return -1

● SELF = second object, return 0

● SELF > second object, return +1

● Undefined comparison, return NULL

Let's look at an example of this type of function:

CREATE TYPE Location_t AS OBJECT (

AND the_location.longitude = SELF.longitude

AND the_location.altitude = SELF.altitude THEN

Trang 15

END;

END;

This ORDER member function will allow us to make simple comparisons such as:

IF location1 > location2 THEN

plant_a_flag;

END IF:

Although not recommended, your ORDER method can return NULL under certain situations, and the object comparison itself will evaluate to NULL That is, if our object type body were rewritten as follows:

CREATE TYPE BODY Location_t

AND the_location.longitude = SELF.longitude

AND the_location.altitude = SELF.altitude THEN

operator Using the second version of the Location_t body, the expression below will always be true!

IF (location1 < location2) IS NULL THEN

Suffice it to say that returning NULL from a comparison function is not particularly helpful

There is nothing magic about the name you give the MAP and ORDER functions In fact, other than

in the type definition statements, you may never refer to this name An added bonus of using MAP or ORDER functions is that they enable you to do things like ORDER BY and GROUP BY the object in SQL statements

Trang 16

Which should you use MAP or ORDER? To some extent, it's a matter of what makes sense to your application, but keep in mind the following restrictions and qualifications:

● A MAP method is more efficient than the equivalent ORDER method

● If you plan to perform hash joins on the object in SQL, you must use MAP, because this type

of join requires a value to hash

● A MAP method is particularly appropriate if you are sequencing a large series of objects, while an ORDER method is more useful if you are comparing two objects

18.3.6.2 Equality comparisons

If you don't create a MAP or ORDER method, Oracle allows you to test only for equality of two

different objects Two Oracle objects are "equal" if and only if they (1) are of the same object type; and (2) both have attributes with identical values Object attributes get compared one at a time, in order, and the testing stops when the first mismatch is discovered

Here is an example of testing for equality:

IF the_1997_spec = the_1998_spec THEN

Or, if we had one table of marketing specs per year:

CREATE TABLE marketing_1997 OF Marketing_spec_t;

CREATE TABLE marketing_1998 OF Marketing_spec_t;

then we could compare from within SQL by using the VALUE operator:

SELECT s97.make, s97.model

FROM marketing_1997 s97,

marketing_1998 s98

WHERE VALUE(s97) = VALUE(s98);

NOTE: Default equality comparisons work only if the object table contains attributes

that Oracle knows how to compare For example, they will work on objects with scalar

attributes, but they will not work on objects with collection attributes, embedded object

types, REFs, or LOBs Also, if you create a MAP or ORDER member function, you

override Oracle's ability to perform the default equality test by comparing all the

attributes

18.3.7 Privileges

Trang 17

While there are two categories of users to whom object privileges may be granted, programmers and end users, there is only one Oracle privilege that applies to object types: EXECUTE Let's look at how this privilege applies to DDL (typically for programmers) and DML (typically for end users)

18.3.7.1 DDL

Let's say that you are the Oracle user named SCOTT and you have created an object type Pet_t You want to grant JOE permission to use this type in his own PL/SQL programs or tables All you need to

do is grant the EXECUTE privilege to him:

GRANT EXECUTE on Pet_t TO JOE;

Joe can then refer to the type using schema.type notation:

CREATE TABLE my_pets OF SCOTT.PET_T;

In the same fashion, the grantee does not have permission to use the constructor or other object

methods unless the object type owner has granted the user EXECUTE privilege on the object type

18.3.7.3 Rights model

Suppose that the owner of a package grants me EXECUTE privileges on it in Oracle7 Whenever I execute the package, I am actually using the owner's privileges on tables, views, and the like I need

no privileges on the underlying structures This definer rights model can be very useful in

encapsulating the table data and protecting it from change except through the package

As mentioned earlier in the chapter (see the Sidebar called "Encapsulation of Persistent Objects in Oracle"), the owner rights model may have a negative impact on object reuse, and it's conceivable

that an object-relational database like Oracle could implement an invoker rights model for object

methods As with all new technology, we will simply have to wait and see whether such a change

Trang 18

comes about, and if it does, what sort of impact it will have on existing applications

Previous: 18.2 Oracle

Objects Example

Oracle PL/SQL Programming, 2nd Edition

Next: 18.4 Manipulating Objects in PL/SQL and SQL

18.2 Oracle Objects Example Book Index 18.4 Manipulating Objects in

Trang 19

Previous: 18.3 Syntax for

Creating Object Types

Chapter 18Object Types

Next: 18.5 Modifying Persistent Objects

18.4 Manipulating Objects in PL/SQL and SQL

In this section we look more deeply into the constructs and concepts you will need in order to master

to use objects in your applications There are three different ways you can initialize an object:

● Use the default constructor

● Make a direct assignment

● SELECT INTO or FETCH INTO

In addition, after an object is initialized, it can be stored in the database, and you can then locate and use that object using several new language constructs:

● REF

● VALUE

● DEREF

18.4.1 The Need to Initialize

The designers of the PL/SQL language have established a general convention that uninitialized variables are null.[12] Object variables are no exception; the term for this uninitialized object

condition is "atomically null." Not only is the object null, but so are its individual attributes To illustrate, let's take a trip back to the pet shop

[12] One significant exception is the Version 2 table datatype, known as index-by

tables in Version 3, which are non-null but empty when first declared In PL/SQL8,

uninitialized nested tables and uninitialized VARRAYs are, in fact, null

Since all pets need a home, we might want to create an address object type:

CREATE TYPE Address_t AS OBJECT(

street VARCHAR2(40),

city VARCHAR2(20),

state VARCHAR2(10),

Trang 20

IF cerberus_house.street IS NULL also TRUE

The nullity of the elements in PL/SQL follows somewhat unpredictable rules; uninitialized RECORD variables have null elements (as with objects), but uninitialized collections have elements whose nullity is not defined As with collections, when an object is null, you cannot simply assign values to its attributes; if you do, PL/SQL will raise an exception Before assigning values to the attributes, you

must initialize the entire object

Let's turn now to the three different ways a PL/SQL program can initialize an object

18.4.1.1 Constructors

A constructor is a special method that allows the creation of an object from an object type Invoking a constructor is a way to instantiate (create) an object In Oracle 8.0, each object has a single default constructor that the programmer cannot alter or supplement

The default constructor:

● Has the same name as the object type

● Is a function rather than a procedure

● Accepts attributes in named or positional notation

● Returns an object

● Must be called with a value, or the non-value NULL, for every attribute; there is no

DEFAULT clause for object attributes

Notice how the name of the constructor matches the name of the object type, which may look odd at first glance (unless you're already an object-oriented programmer) The following declaration assigns

an initial value to the cerberus_house object:

DECLARE

cerberus_house Address_t := Address_t('123 Main',

'AnyTown', 'TX', 'USA');

18.4.1.2 Direct assignment

Trang 21

When assigning one object to another, you create a new object that starts life as a copy of the

original In the following example, minotaurs_labyrinth gets initialized using direct assignment

18.4.1.3 Assignment via FETCH (with SELECT)

Assuming that there is a "houses" table of Address_t objects, we can use a SELECT statement to retrieve from the database into a PL/SQL object PL/SQL provides the VALUE keyword (described below) to retrieve the contents of the entire object:

Trang 22

While seeming quite reasonable, this kind of an assignment will clearly not achieve the desired result

It bears repeating: always initialize your objects!

18.4.2 OID, VALUE, REF, and DEREF

The Oracle objects option provides an initially bewildering set of constructs for locating and referring

to persistent objects Getting to know them may take some time, but understanding them will be essential to "doing objects right." Table 18.3 summarizes these schemes and the following sections look at them in more detail

Table 18.3: Schemes for Referring to Persistent Objects

Object identifier

(OID)

An opaque, globally unique handle, produced when the object is stored

in the database as a table (row) object

This is the persistent object's handle; it's what REFs point to Your program never uses it directly

VALUE An operator In SQL it acts

on an object in an object table and returns the object's "contents." Do not confuse this keyword with the VALUES keyword that appears in the INSERT statement

Used when fetching a table (row) object into

a variable, or when you need to refer to an object table as an object instead of a list of columns

REF A pointer to an object

May be used within a SQL statement as an operator,

or in a declaration as a type modifier

Allows quasi-"normalizing" of relational databases and "joining" of object tables using "dot navigation." In PL/SQL, REFs serve as input/output variables

object-DEREF Reverse pointer lookup for

Trang 23

Have you ever used an arbitrary number (maybe an Oracle sequence) as a table's primary key? The benefits are many chief among them that you can often hide it from the users and never have to worry about them wanting to change the key value! Object identifiers are a lot like your arbitrary numbers, except that they are assigned by Oracle When you create a table of objects, Oracle adds a hidden field that will hold the object identifier for each object Oracle also automatically creates a unique index on this column When you insert an object into the table, Oracle automatically assigns the object a rather large but hidden object identifier (OID) The OID is:

Opaque Although your programs can indirectly use the OID, you don't typically see its value

Potentially globally unique across databases The OID space makes provisions for up to 2128objects (definitely "many" by the reckoning of the Hottentots).[13]

[13] Oracle could one day use an OS-dependent function to make OIDs globally unique; that way, no two OIDs could have the same value, even on different machines that are configured identically Perhaps object navigation will be possible without database links (In case you're wondering, the Hottentots had a four-valued counting system: 1, 2, 3, and "many.")

Capable of being synthesized from a primary key so that objects can be retrofitted onto

relational schema using object views

Preserved after export/import by the owner, unlike ROWIDs This could allow objects to be

distributable across databases in the future (contrast with ROWIDs, which are tied to a

particular database)

In addition, unless you are using primary key-based OIDs in object views, OIDs are immutable That

is, even if you want to change the binary value of an OID, you can't do it unless you delete and

recreate the object, at which point Oracle will assign a new OID

Not all objects have an object identifier In particular, objects stored in PL/SQL variables lack a referenceable OID, as do column objects A column object only "makes sense" within the context of its row, and the row will have other means of unique identification Implementors must sometimes choose between embedding an object and making it referenceable.[14]

[14] This approach is 180 degrees off from relational industry experts who assert that

OIDs should not be used for row identification, and that only column objects should

have OIDs See Hugh Darwen and C J Date, "The Third Manifesto," SIGMOD

Record, Volume 24 Number 1, March 1995.

Hidden Columns Exposed

The name of the column where Oracle8.0.3 stores object identifiers is SYS_NC_OID$ This column

is "hidden" in that you won't see it when you "describe" the table in SQL*Plus, but it exists for every object instance (row) in an object table It contains a 16-byte binary value; although this value is selectable from SQL*Plus, it should never be stored or manipulated in your programs Oracle has

Trang 24

hidden the OID to prevent hardcoding memory addresses into programs a dangerous practice in any environment Moreover, the OID structure could change in future Oracle versions

There's another hidden column, SYS_NC_ROWINFO$, which provides a representation of the

constructor for the row object The same caution applies it's interesting to look at, but do not rely

CREATE TABLE foos OF foo_t;

INSERT INTO foos VALUES (1, bar_t

-FOO_T(1, BAR_T('apple', 'banana', 'cherry'))

Oracle provides constructs such as REF( ) and VALUE( ) so you don't need direct access to these hidden columns In fact, you can get the constructor out of SYS_NC_ROWINFO$ in an Oracle-supported manner as follows:

SELECT VALUE(f) FROM foos f;

VALUE(F)(ID, BARS)

-FOO_T(1, BAR_T('apple', 'banana', 'cherry'))

18.4.2.2 REFs

Trang 25

Oracle8 "reference" datatypes are destined to cause more than a few knitted brows in the Oracle user community The confusion starts with the fact that REF has two different yet related meanings,

depending on context Toss in the fact that some objects have REFs and some don't It's best to invest

a little extra time early on to understand REFs if you want to avoid increasing your gray hair count (or, in my case, the size of my forehead)

The main reason that the reference concept is so critical is that REFs are the best way of uniquely referring to object instances REFs are the way that we "see" object identifiers REFs are the basis of object relationships and object "joins."

18.4.2.2.1

REF as operator

In a SQL statement, when you need to retrieve a table object's unique identifier, you will use REF In

this case, REF operates on a row object, accepting as its argument a table alias (also known as a

correlation variable ) As hinted earlier, REF cannot operate on column objects or otherwise nested

objects, because such objects do not have an OID REFs are constructed from (but are not identical to) OIDs; only objects with OIDs get to have REFs pointing to them

Syntactically, to retrieve a pointer from a table of objects, you will use:

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

TỪ KHÓA LIÊN QUAN