Oracle Databases On The Web Learn To Create Web Pages That Interface With Database Engines.9781576100998
Oracle Databases On The Web Learn To Create Web Pages That Interface With Database Engines.9781576100998
Click Here!
Click Here!
ITKnowledge
Introduction
What's on the CD-ROM
Please Select
Dedication
Extensibility
New Database Design—The ISA Construct
Summary
Frame Procedures
List Procedures
Character Format Procedures
Physical Format Procedures
Form Procedures
Table Procedures
HTP/HTF Parameters
Summary
Index
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Table of Contents
Please Select
Introduction
For the past several years, the Oracle database management system has enjoyed
dominance in the worldwide information systems marketplace. Oracle’s excellent
reputation has been based on the stability of its Oracle7 Server. In our many years of
database and application experience, the Oracle DBMS stands out as being highly
reliable and recoverable, two of the main features that information professionals
depend on daily. However, until recently, it has been very difficult to get information
out of an Oracle database and onto the World Wide Web. Now that you can use
Oracle’s WebServer to create Web page front-ends for Oracle databases, developers
everywhere are struggling to learn all the facets of WebServer to integrate their
databases with the Web.
As is the case with any nascent technology, the pragmatic use of Oracle’s WebServer
is not yet clear to Oracle developers. In the meantime, we have written Oracle
Databases on the Web to simplify the process of using Oracle’s WebServer and
explain the development of Web-based Oracle applications in easy-to-understand
terms. Interfacing a complex and robust database such as Oracle with the World Wide
Web is not a simple task, and there are many hidden pitfalls that must be addressed
before it you can easily interface Oracle with Web pages. This book hopes to point out
those pitfalls, and the paths you can take to get around them.
Oracle Databases on the Web introduces the basic concepts of creating a Web page
and interfacing that page to the Oracle database management system. We use Oracle’s
WebServer product to illustrate all the examples in the book, but the focus will be on
generic techniques that can be used to interface any Web page with any Unix-based
database, using proven Web interface techniques.
This book begins by discussing the basics of the World Wide Web and WebServer’s
architecture, including a detailed chapter on the installation of WebServer. It then goes
on to discuss how to manage WebServer applications, and contains separate detailed
chapters on various Oracle utilities that you will need to know about. The book also
contains chapters on how to tune Web databases and Web-based SQL. Basically,
we’ve tried to include everything you might need to know about WebServer and
developing Web-based databases in this book.
The Oracle WebServer will become a very hot topic as mainstream IS shops begin to
enter the World Wide Web to better service their customers. Oracle Databases on the
Web will help to reduce their fear of this technology, and aid Oracle developers in
their task of creating robust and functional Web pages that interface with Oracle.
The authors welcome feedback and comments. Please address email to:
Don
[email protected]
Burleson:
Bob Papaj: [email protected]
Table of Contents
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Table of Contents
Please Select
What’s on the CD-ROM
The companion CD-ROM for Oracle Databases on the Web includes:
See the readme files in each folder for acknowledgments, descriptions, copyrights,
installation instructions, limitations, and other important information.
Requirements
Software:
Oracle7
Hardware:
Platform: Pentium
Operating System: Windows NT
RAM: 32 MB
Table of Contents
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Table of Contents
Please Select
Dedication
We dedicate this book to our loving families, and to all our friends who helped support
us through the trials and tribulations of writing this tome.
Bob Papaj
Don Burleson
Table of Contents
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/about_author.html4/03/2005 6:15:10
Oracle Databases on the Web:Evolution Of The Internet, The World Wide Web, And Databases
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 1
Evolution Of The Internet, The World Wide Web, And
Databases
The Information Superhighway began with the development of a wide-area network
(WAN) that eventually became the Internet. In its most basic form, the Internet is a
world-wide network of subnetworks; it is the backbone for the global transportation of
data. The predecessor of the Internet was a Department of Defense project called
ARPANET (Advanced Research Projects Administration Network). ARPANET was
developed in the early 1970s to assist researchers working in the United States defense
industry, as well as a few associates in other countries.
ARPANET grew from a network of a few computers in 1971 to over 1,000 by 1984.
In 1986, the U.S. National Science Foundation established NSFNET to provide
network connections for research institutions. Soon, NSFNET became the new
backbone for the Internet. By 1990, ARPANET had dissolved, but the Internet
continued to grow via NSFNET. Today, commercial networks run the Internet and
have expanded the Internet to provide millions of instantaneously accessible locations
to surfers from around the globe.
Internet Basics
Despite its overall complexity, the Internet has just a few major components: the
Note: While the Internet is very established throughout the Americas and
Europe, expansion of the Internet into the remotest parts of the world is
constrained by the lack of high-speed phone lines. These high-speed long-
distance lines are different from the phone lines we deal with on a daily basis.
High-speed phone lines are point-to-point lines where the circuit can be open
continuously between connections. Point-to-point lines also have a much
greater capacity for carrying data than basic phone lines. The demand for
higher capacity lines, similar to those used in WANs, resulted in the
production of high-speed, high-volume lines called T1 and T3 service lines.
The T3 line is the faster of the two and is used throughout the North American
Internet backbone.
Connection Costs
Despite the critical nature of the Internet, it’s not totally clear who is responsible for
costs associated with installing and maintaining connections among local networks.
The cost of connecting a local network to the Internet is commonly paid for by the
owner of the local network. The local network owner negotiates a connection with a
site already connected to the Internet and pays for a dedicated line that connects the
local network to the Internet site. Thanks to the NSFNET project, the National Science
Foundation paid for the T3 network backbone in North America.
Internet Protocols
There are three levels of protocols used by computers to communicate with each other:
network, transport, and application. Network protocols coordinate the transmission of
information, transport protocols manage the integrity of the data, and application
protocols format the data for transmission. The network protocol used by the Internet
to get information from one computer to another is called Internet Protocol (IP).
Messages delivered by the IP are called packets. The Internet has two transport
protocols for coordinating the integrity of network transmissions: TCP (Transmission
Control Protocol) and UDP (User Datagram Protocol). Transport protocols determine
whether packets have arrived at their destination, and if so, the protocol assembles the
packets in the proper order. As you saw in Table 1.1, there are many applications on
the Internet—each of which has their own application protocol.
On the Internet, the TCP and IP protocols are often paired together in their usage and
jointly referred to as TCP/IP. For the IP to do its job, it needs to identify sites for data
transmissions. Under IP, each network and each computer attached to the network has
a fixed address. The Internet address is a 32-bit address, partitioned by four 8-bit
numbers that identify the computer and its local network. The four bytes (each byte
represented by 8 bits) of the address are separated by periods (e.g., 155.222.8.19) and
identify either a network number or a host number, depending on the value of the first
byte. The first byte (in this case ‘155’) falls within a standardized range of values that
will determine the composition of the IP address. In this example, bytes one and two
represent the network, and bytes three and four represent the host. The network
component is assigned when the local network registers for an Internet connection
with the Internet Network Information Center (InterNIC or NIC). NIC gives a range of
Internet addresses to the local network’s administrator, who then assigns the numbers
to host computers on the local network.
Click Here!
Click Here!
ITKnowledge
Many sites recognize the need to track the locations of remote databases and systems
on the Internet while providing “location transparency” to their users and
programmers. Location transparency refers to a condition whereby the application
requests data as if it were local, yet the data may reside thousands of miles away.
Domains are especially important in situations of horizontal partitioning, where data
tables with identical names are kept at numerous locations. Domains establish a logical
hierarchy of physical locations for any distributed enterprise on the Internet, as shown
in Figure 1.1.
The real power of the Internet comes into play when Domain Name Services are used
to replace the IP address number with a meaningful mnemonic. For example, the IP
address 223.222.45.76 could be given the alias “litterbox,” and Internet users could
then Telnet to litterbox without knowing the IP address.
Internet Applications
Once a backbone had been created for the Internet, software applications were created
to allow easy use of the Internet. Some of these applications on the Internet are very
common (email, Telnet, and FTP, for example) because they are bundled with the
network portion of the Unix operating system—the most common Internet operating
system. Other Internet applications (such as Gopher, WAIS, WWW, and Archie) are
not a part of the operating system and function as standalone applications.
Unfortunately, standalone applications are not always good for sharing data between
multiple users because there is no common repository for the data. In order to properly
share data with a standalone application, users would have to execute the application
on the machine with the data or the data would have to be replicated on many
computers.
Fortunately, the client/server architecture can help in the goal of data sharing. Network
applications work on the client/server model, which distributes the work of one
application across two programs, a client and a server. Usually, data is accessed
anonymously because it is not necessary to know someone or be known by someone to
access data on the Internet. An application is started on the client side that collects
details about what is needed by the user, and the client program then proceeds to
connect over the network to a server program that controls the information requested.
This dialogue between a client and a server is accomplished through application
protocol interfaces, which are commonly called APIs. The client-side software formats
user requests using the same API as the server. It then dispatches the request by a
program that formats the message and transmits it across the network to the server.
The server receives the client request, finds the information resource, formats the
results in an application protocol, and passes the response to a protocol handler to
transmit the requested information back to the client.
On the client side, client programs are always ad hoc because a client process is started
by a user request. Of course, the server must be ready at all times to respond to a client
request, and server programs run continuously, listening for the client requests on their
assigned port numbers. Please note that the client/server architecture does not require
that the client and the server run on different platforms. Client/server programs can run
on the same machine or can run on different machines with heterogeneous operating
systems. They can also be defined to support multiple network protocols. Each client
program provides a user interface, which may be a character-based interface
supporting text only, or a graphical user interface (GUI) supporting text and images
like MS Windows. Client programs must execute on an Internet-attached server to
access the data repositories connected to the Internet.
The World Wide Web and the Internet are occasionally interpreted as being one and
the same, but they are not. However, the Internet and the Web have been integrated
into a powerful behemoth networking system providing links between text, images,
and audio information. As we learned earlier, the Internet is nothing more than the
physical network of computer hosts. The World Wide Web, on the other hand, is a
collection of protocols and standards used to access the vast array of information
across the Internet. The World Wide Web uses special applications to retrieve the data
on the Internet and can be thought of as residing on top of the basic Internet
foundation.
The World Wide Web is a very new phenomenon. Since the Web sprang up from its
infancy just a few short years ago, it has become the major driving force in worldwide
computing. The most fundamental aspect of the World Wide Web is the hypertext link,
the procedure for connecting information repositories across the Internet. The
hypertext concept, which allows users to access information in a nonlinear fashion, is
not new and was developed in the 1940s by an engineer named Vannevar Bush. He
visualized users following trails of information in multiple directions and felt this was
essential to accommodate the large amounts of data being generated at that time.
The actual term hypertext was coined by Ted Nelson in a book he published called
Literary Machines (South Bend, Ind., 1981). In this book, Nelson outlined a system
called Xanadu, which made use of hypertext links. While Nelson is credited with the
original definition, the person most credited with refining hypertext links is Tim
Berners-Lee, who in the 1980s was employed at the European Particle Physics
Institute (CERN) in Geneva, Switzerland. It was there that Berners-Lee developed a
hypertext system used in the physics community to share information. Berners-Lee
called the system Enquire-Within-Upon-Everything. This system provided hypertext
links consisting of titles, text, and lists of bidirectional-text links.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Building on their success, Berners-Lee and his associate Robert Caillian compiled the
original design documents for a hypertext system as a way to link and access
information of various kinds on a web of nodes. The network of links was called the
World Wide Web. Contrary to the existing Internet hierarchical systems, which had a
rigid path structure for accessing information, the World Wide Web could be accessed
without hierarchical access paths. In addition, the design document specified several
principles of the Web such as:
Berners-Lee developed the original hypertext project on a NeXT workstation, and the
first hypertext prototype was operational in late 1990. A scientist named Nick Pellow
also participated in the project and developed the world’s first Web browser. In May
1991, the project came together and the World Wide Web became readily available to
the general public. The Web was greatly assisted in its development by the many
discussions that transpired on existing Internet newsgroups, such as alt.hypertext and
comp.infosystems.www.
An early application of hypertext released in 1987 was HyperCard for the Macintosh.
HyperCard enabled users to peruse databases in non linear tracks, very similar to
hypertext browsing techniques. As an application, HyperCard grew rapidly in use
because it was provided at no charge and was bundled with the Macintosh operating
system. HyperCard combined embedded text links with images and sounds, and
provided a dazzling display platform for nontextual information. This concept of
merging hypertext with multimedia objects became known as hypermedia.
The World Wide Web is best described as a Windows-style data transmission tool that
enables a collection of multimedia documents to be connected by hyperlinks. Web
technology enables users to click on words and images in a document to access other
documents, such as text, images, sounds, and movies. Web applications can be
restricted to internal LANs (intranets), or they can be set up to access the full Internet.
Most Web development is currently taking place within corporate boundaries on
intranets. An intranet is basically a Web application that is only available to users of a
closed, subnet of nodes. Many companies remain wary of security issues outside of
their protective firewalls (firewalls often act as LAN gateways to the Internet).
Intranets can be used for sending and receiving email, distributing and retrieving
information, and coordinating departmental and interdepartmental projects.
Initially, the Web was designed to transmit text documents, but it became multimedia-
based with the development of Web browsers. A Web browser provides a GUI front
end to the multimedia resources available on the Web. The first Web page accessed on
a Web server is called the home page, which generally describes and provides links to
all the information retrievable on that server. Clicking on a highlighted box or
underlined text opens a link to other Web pages containing additional information.
Links can take users to information residing on the same server or on another Internet
server located anywhere in the world.
There are primarily three standard elements that comprise the Web: URLs (Uniform
Resource Locators), HTTP (Hypertext Transfer Protocol), and HTML (Hypertext
Markup Language). URLs are the Internet addresses that we commonly see (such as
http://www.coriolis.com). URLs help to locate data on the Internet by addressing
resources across multiple protocols. URLs can identify documents through HTTP,
specify email addresses, transfer files through FTP, and access Gopher menus.
The format of a URL changes based on the protocol being used. A URL can be broken
down into three components: the protocol to be used, the server where the connection
will be made, and the path for the file to be accessed. In general, but not universally,
the format of the URL is:
protocol://servername:port/path
Usually the “:port” section is omitted, and the URL will use a default port for that
protocol. The port number is an identifier that is assigned to software programs that
communicate between networked computers. The server name may be specified in
either upper- or lowercase. Also, it can be represented as an IP address or hostname.
The IP address is a series of numbers that identify the host and the network location of
the host. The hostname is usually synonymous with the domain name. Let’s try an
example:
spartan.spearsinc.com
The domain name in this example is broken down as follows, reading from right to
left. The rightmost part of the domain name is referred to as the zone, in this case
“com,” which categorizes this as a commercial organization. Table 1.2 shows a list of
valid three-character zone names that are commonly used on the Web. There are also
two-character zone names that are infrequently used and are geographic identifiers
(such as .uk for United Kingdom and .it for Italy). Moving to the left is the string
“spearsinc,” which identifies the particular company or organization. Finally, furthest
to the left, the hostname “spartan” specifies the lowest-level name of the server. Often,
on the Web, you’ll see the hostname specified as “www.”
Note: URLs are almost always case-sensitive. Be sure to enter them exactly
as you see them written in the address.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select In general, the World Wide Web transfers information across the Internet using the
HTTP protocol. In order for HTTP to get information from a server to a client, three
steps occur:
The status code usually indicates that the request was successful, but other codes may
be returned indicating various errors in transmission. The object information fields can
specify an enormous amount of information, including:
The client browser can use the content-type field when determining how to process
what was retrieved (for example, a graphic image, a sound, and so on). In addition,
browsers can use the last-modified field to reduce repetitive transfers of large images
and bitmaps. The most recent transfers are cached within the browser and will not be
transferred again when requested unless the last modified field has changed.
HTTP
HTTP has been defined as a “stateless” protocol used to increase data transfer rates.
But what does “stateless protocol” mean? It means that HTTP is not required to
remember any information about a connection from one request to another. The state
of the protocol does not have to be defined internally and can be set within the URL.
HTTP can have only one request per connection, which also makes it a
“connectionless” protocol. The client-to-server connection is severed after each
request is resolved. A new connection must be established to the server for every client
request. Retrievals of Web pages that contain many graphic images can take
considerable time to complete because a connection must be established for each
image. Some browsers, like Netscape and Microsoft Internet Explorer, will transfer
multiple documents simultaneously by opening multiple connections; many other
browsers transfer documents more slowly, because they are restricted to one open
connection at a time, per request.
The third leg of the World Wide Web is Hypertext Markup Language (HTML), which
is an outgrowth of Standard Generalized Markup Language (SGML). Other markup
languages include LaTeX, RTF, and Frame. The markup languages define areas of text
by “tagging” them with a specific format for a specific use. Hypertext links can be
created between documents with HTML to provide the transport mechanism. This is
accomplished by marking documents with code associated with other documents to
crisscross the Internet, forming the Web.
In order to access the Internet and the World Wide Web, a computer called a network
host must exist and be connected to the Internet. Local area networks (LANs) must
connect to one of these network hosts. The local network’s connection point to the
Internet is called a router, which is a special computer bridging the LAN to the
Internet. A series of dedicated phone lines creates the long-distance part of the
Internet’s physical network. Remote computers use dedicated phone lines to connect
to LANs that are connected to the Internet.
Today, the Internet has over 30 million users with thousands of new users being added
every day. Ninety-five countries have access to the Internet, and more than 145
countries have access to email. Regulators predict at least a 100 percent rate of growth
each year for the Internet.
Internet-based systems developed in the 1990s may seem revolutionary, but they are
no less revolutionary than the demise of punched cards brought on by the introduction
of GUI interfaces in the 1970s and 1980s.
the state of online systems has changed relatively little since the 1960s. Online
transaction systems continue to process record-oriented information, and if we factor
out the convenience of a GUI and a mouse, the core nature of these systems has
remained unchanged. However, this does not imply that Internet-based client/server
and distributed databases are only a facade.
As processors continue to increase in speed and decrease in cost, the next revolution
will exploit the inherent power of client/server systems and change the way
information systems function, not just how they appear. For example, imagine high-
speed processors on everyone’s desk, with each machine having the power of an IBM
3090 mainframe. The client/server component would then become more of a data
server than a shared processor, and corporate information could be extracted and
manipulated freely within the information domain.
The greatest challenges over the next decade will be the management of distributed
data. Centralized corporate servers must be built and managed so that a user,
regardless of geographical location or computer platform, can instantly access and
manipulate data. These new servers will open up new career fields and new jobs, such
as the Object Administrator.
Click Here!
Click Here!
ITKnowledge
Please Select However, it is interesting to note that object-oriented languages do not follow the
pattern that we have seen in previous programming languages. If we take a look at
people costs versus CPU costs, we find that the procedural language of the day was
suited to the economic situation at the time.
Figure 1.2 shows that the early second-generation languages are designed to be high in
people resources, but very efficient in CPU consumption. This is to be expected
because, in the early 1960s, people costs were relatively less expensive than CPU
cycles. Programming competitions in the 1960s judged the contestants by how
efficiently they could write a program, not by how fast they could write a program.
Processor cycles were precious, and the programmers were taught to carefully hand-
execute each line of code before submitting it to the compiler.
As time passed, people costs remained constant while the costs of CPU time began to
drop dramatically. Here we see the introduction of the third-generation languages,
such as COBOL and Fortran. These languages recognized the falling costs of CPU
cycles relative to people costs, and they were designed to allow programmers to
become more productive, even if it meant requiring more processing time to compile
their programs. We still see carryovers from the earlier days, in features such as 66-
level entries in COBOL that serve only to save a small amount of memory during
execution time, but there is a clear trend to make procedural language programming
more productive for the programmer.
As processing costs fell by a factor of 100, the fourth-generation languages gave even
more recognition to the new economic reality. By fourth-generation languages,
programmer costs amounted to the majority of managers’ budgets, and the
marketplace was demanding languages that could make their programmers more
productive. Figure 1.3 shows the introduction of high-level languages such as SAS,
Focus, and “Wizard-based” environments, such as Microsoft Visual Basic and
Microsoft Access.
However, one must note that the fall in processor costs cannot continue forever. As we
maximize the potential of silicon technology, we see that each marginal improvement
in speed and power is becoming more expensive. We have already maximized the
potential of silicon technology, as seen in the flattening of the CPU curve in Figure
1.2. When a new technology arrives, say Gallium Arsenide, we may see another surge
in declining processor costs. It is also interesting to note that computer programmers
are worse off today than they were in the 1960s (in net-present value dollars). While
programming skills have commanded high salaries, the programming profession has
fallen victim to the friendliness of the procedural languages. Today, a 10-year-old can
create and manipulate a database by using friendly tools with Wizards, and it is no
longer necessary to have a master’s degree in computer science to program a
computer. Consequently, we see a trend away from the high salaries of the 1960s,
when programming was a skill reserved for those who could afford the cost of many
years of expensive training.
Given these trends, we might expect to see the next generation of languages become
even friendlier, allowing automatic code generation with a minimum of technical
expertise. Here is the rub: Instead of seeing a new generation of languages that are
even friendlier for the programmer, we are seeing the age of object-oriented
programming. Object-oriented languages such as C++ and Smalltalk, are a far cry
from the expectations of the programming community for a high-level, friendly
language.
With regard to databases, we see a similar backward trend. The first commercial
databases, such as IBM’s IMS database, were very difficult to navigate, and it took
programmers months of training to begin to use these complex database engines.
Then, the advent of the CODASYL network model provided a standard Data
Manipulation Language (DML), but database access was still achieved by carefully
navigating pointer lists. The introduction of the relational model and Structured Query
Language (SQL) made database access easier than ever. SQL became so popular that
even end users could retrieve data from their own tables without any intervention from
When object-oriented databases started to become popular, we saw a trend away from
the simple SQL database access. Figure 1.4 shows this evolution of database
technology.
Click Here!
Click Here!
ITKnowledge
Please Select
Objects And The Internet
Let’s take a look at a human analogy to the object-oriented approach. It is very natural
for humans to recognize objects and to associate objects with their classes. It is also a
very natural concept to associate an object with its expected behaviors.
Even as very young children, we learned to associate objects and behaviors with
certain characteristics of objects. For example, it is not uncommon to visit the zoo and
hear a three-year-old call all four-legged animals “doggies.” The child has learned to
associate an object class (dog) with a data at tribute (four legs). Later, a child will
refine her object-oriented paradigm and associate other data attributes with animal
objects. A child also learns to associate behaviors (such as playing, having fun, or
pain) with different visual and auditory stimuli.
Adults develop the same associations between objects and behaviors. There have been
hundreds of psychological studies that prove that expectations, or the association of
behaviors to attributes, affect interactions among people. Humans are also familiar
with the concept of abstraction. Intangible objects, such as time, are easily understood.
Rather than rebuild the Oracle engine as an object-oriented architecture, Oracle has
decided to keep the base relational engine and add object functionality on top of the
standard relational architecture. While claiming to be an active member in the Object
Management Group (OMG), Oracle has departed from the OMG’s standard for “pure”
object databases as defined by the Object Data Management Group (ODMG). Oracle’s
intent is to provide a generic relational database while extending the architecture to
allow for objects, such as:
Rather than being constrained to the basic relational data types of INT, VARCHAR,
and FLOAT, future versions of Oracle may allow the definition of data types that may
be composed of many subtypes. For example, the following data definition could be
implemented as an ADDRESS data type:
03 ADDRESS.
05 STREET-ADDRESS VARCHAR(30).
05 CITY-ADDRESS VARCHAR(30).
05 ZIP-CODE NUMBER(5).
In this manner, aggregate data types can be defined and addressed in a table definition
just like any other relational data type. In the following example, we see the
phone_nbr and address data types being used in a table definition:
Here we see that a single data field in a table may be a range of values or an entire
table. This concept is called complex, or unstructured, data typing. With this approach,
the domain of values for a specific field in a relational database may be defined. This
ability to nest data tables allows for relationship data to be incorporated directly into
the table structure.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The engine allow for the direct coupling of a database entity (such as a table or object)
with a set of predefined behaviors. In this fashion, calls to Oracle will be made by
specifying an object name and the method that is associated with the object. For
example:
This call tells Oracle to invoke the add_new procedure that is attached to the
CUSTOMER object using the supplied parameters. As you might expect, this new
way of invoking database calls has important ramifications for the developers and
Database Administration (DBA) staff.
For developers, applications will become SQL-less and will consist of calls to stored
procedures. Of course, this has the important benefit of making applications portable
across platforms, while also making it very easy to find and reuse code. In addition,
because each method is encapsulated and tested independently, the pretested methods
can be assembled with other methods without the worry of unintended side effects.
The introduction of methods will dramatically change the way DBAs function. Instead
of only managing data and tables, the DBA will also be responsible for managing
objects and the methods associated with each object. These new “object administrator”
functions will need to be defined so that developers know the functions and parameters
of each method.
Abstraction
Abstraction will be defined as the conceptual (not concrete) existence of classes within
the database (see Figure 1.6). For example, a database may have a class hierarchy that
includes classes that do not have any objects. Let’s consider a military database as an
example. A military database may contain the conceptual entities of division,
battalion, squadron, and platoon. Further, assume that the function of the database is
to track only the platoons; therefore, the entity classes of division, battalion, and
squadron may not have any associated objects.
However, this is not to say that there is no purpose for abstract classes. When a class is
defined, it is associated with behaviors, and these behaviors will be inherited by a class
containing an object, such as the platoon class in our example. From a database
perspective, there will be no instances of any objects in our example except in the
platoon class, but higher levels in the class hierarchy contain behaviors that the
platoon objects inherit.
Inheritance
To illustrate, let’s look at an application of this system for a vehicle dealership (see
Figure 1.7). Occurrences of item entities to a dealership are found in the vehicle class.
Beneath the vehicle class, we may find the subclasses car and boat. Within car, the
classes may be further partitioned into classes for truck, van, and sedan. The vehicle
class would contain the data items that are unique to each vehicle, including the
vehicle ID and the year of manufacture. The car class, because it is a subclass of
vehicle, would inherit the data items of the vehicle class. The car class might contain
data items such as the number of axles and the gross weight of the vehicle. Because
the van class is a subclass of car, which in turn is a subclass of vehicle, objects of the
van class will inherit all data structures and behaviors relating to the car and vehicle
classes.
sailboat.compute_rental_charges();
Click Here!
Click Here!
ITKnowledge
Please Select The database will first search for the compute_rental_charges in the sailboat class,
and if it isn’t found, the database will search up the class hierarchy until
compute_rental_charges is found.
Of course, not all classes within a generalization hierarchy will have objects associated
with them. The object-oriented paradigm allows for abstraction, which means that a
class may exist only for the purpose of passing inherited data and behaviors. The
classes vehicle and car would probably not have any concrete objects, while objects
within the van class would inherit from the abstract vehicle and car classes. Multiple
inheritance is also demonstrated by the amphibian_car class. Any instances of this
class will inherit data and behaviors from both the car and the boat classes.
Polymorphism
Polymorphism is the ability of different objects to receive the same message and
behave in different ways. This concept has many parallels in the real world. For
example, an event such as a volcanic eruption may have many different effects on the
living things in the area. The poisonous gasses could kill air-breathing animals while
at the same time nourish small marine organisms nearby. The single behavior
eruption has different effects on objects within the animal class. Another analogy can
be found in the business world. For a personnel manager, a promotion event will
cause different behaviors depending on the employee class affected by the promotion
event. Management objects will receive stock options and country club memberships,
neither of which are offered to part-time objects.
Ronald Popeil was a master of polymorphism. Many folks may remember the heyday
of Popeil and his company called “Ronco.” In the 1970s, Popeil spent tens of millions
of dollars on television advertising, and created ads where the polymorphic nature of
his products were demonstrated. Consider the statement, “It’s a hair cream AND a
floor wax!” If that statement were true, the method spread_it_on would invoke very
different processes depending upon whether we are applying the cream to a floor or a
person’s head.
COUNTER = COUNTER + 1
N$ = "Mr. Burleson"
S$ = "Hello there, " + N$
END
In this example, the + operator is used to indicate addition in one context and
concatenation in another. But what determines which way the operator will function?
Clearly, the Basic compiler knows that the + operator means addition when it is used
in the context where a number is passed as an argument, and it knows that
concatenation is required when character strings are passed as an argument to the
operator.
The implications of polymorphism are that a standard interface may be created for a
related group of objects. The specific action performed by the object will depend upon
the message that is passed to the interface. Because the programmer is no longer
concerned with the internal constructs of the object, extremely complex programs can
be created. The programmer only needs to understand the interface to use the object.
Now, let’s apply polymorphism to the database scenario. All communication between
database objects and their behaviors is accomplished by using messages. A message is
normally the name of a behavior that is tightly coupled to an object type, such as the
messages customer.display_ address(“Sam Jones”) and order.display_details(“123”).
For example, consider two objects, rush_order and cod_order, that belong to the
order class.
PLACE_ORDER(PREPARE_INVOICE(COMPUTE_CHARGES))
IF (RUSH_ORDER)
COMPUTE SHIPPING = TOT_AMNT * .25
ELSE
COMPUTE SHIPPING = TOT_AMNT * .10
IF (COD_ORDER)
COMPUTE TOT_DUE = TOT_AMNT + SHIPPING
ELSE
COMPUTE TOT_DUE = 0
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Encapsulation means that each object within the system has a well-defined interface
with distinct borders. In plain English, encapsulation refers to the localized variables
that may be used within an object behavior and cannot be referenced outside of that
behavior. This closely parallels the concept of information hiding. Encapsulation also
ensures that all updates to the database are performed using the behaviors associated
with the database objects.
Code and data can be enclosed together into a “black box,” and these boxes may then
function independently of all other objects within the system. From a programming
perspective, an object is an encapsulated routine of data and behaviors. Objects may
contain public variables, which are used to handle the interfaces to the object, and
private variables, which are known only to the object. Once created, an object is
treated as a variable of its own type. For example, an object of class car is created as a
routine with a data type called car and is treated as a compound variable by the
program.
add_line_item that serves to check inventory levels for an item and add items to an
order only if sufficient stock is available. This behavior ensures that orders are not
entered for out-of-stock items. With a language such as SQL, the object-oriented
behavior could be bypassed, and line_item records could be added without regard for
inventory levels.
Because encapsulation and SQL are clearly incompatible, the only conclusion that can
be reached is that encapsulation may be violated in Oracle8 by using ad hoc tools such
as SQL*Plus.
Extensibility
Extensibility is the ability of the Oracle8 engine to add new behaviors to an existing
application without affecting the existing application’s shell. This is an especially
powerful feature because it allows Oracle8 to extend existing classes and to ensure that
there are no unintended side effects from the introduction of a new object class.
For example, consider a company that provides payroll services for businesses in
many states. Some payroll computations are global (e.g., Gross_pay = hours_worked
* payrate), while others are specific to a municipality or state (such as computing
state taxes). Using Oracle8, an existing object class definition can be extended such
that the new object behaves exactly like its superclass definition, with whatever
exceptions are specified. For example, if New York City instituted a new payroll rule
for New York City residents, then the general definition for New York payroll
customers could be extended with a new class definition for New York City payroll
customers. The only method that would be attached to this class definition would be
the code that is specific to New York City; all other methods would be inherited from
the existing superclasses.
Here is a vision of how it might work. After establishing a class hierarchy with the
Entity/Relation model, the principle of generalization is used to identify the class
hierarchy and the level of abstraction associated with each class. Generalization
implies a successive refinement of the class, allowing the superclasses of objects to
inherit the data attributes and behaviors that apply to the lower levels of the class.
Generalization establishes taxonomy hierarchies, which organize the classes according
to their characteristics, usually in increasing levels of detail. Generalization begins at a
very general level and proceeds to a specific level, with each sublevel having its own
unique data attributes and behaviors. Essentially, this hierarchy implies successive
levels of detail, such as “a sedan ISA car, which ISA wheeled_vehicle, which ISA
vehicle”.
In Figure 1.9, the ISA relationship is used to create a hierarchy within the object class,
and all of the lower-level classes will inherit the object class’s behaviors. The ISA
relationship is used to model the hierarchy that is created as the class entity is
decomposed into its logical subcomponents. As you can see in Figure 1.9, customers
may be preferred_customers or new_customers, and orders may be cod_orders or
prepaid_orders, each with its own data items and behaviors.
Summary
While this chapter has discussed three different topics, the intent was for the reader to
develop an appreciation about how the Internet, the World Wide Web, and the
development of objects within Oracle will influence the future of database-enabled
Web pages. It’s very clear from an evolutionary perspective that the Internet will bring
older technology to the forefront, while at the same time provide a vehicle for newer
technologies. Hopefully, future releases of Oracle, as well as WebServer, will marry
the Internet with object databases, so that access to database information will not
require complicated explanations.
Basic GO
Please Select
CHAPTER 2
Oracle WebServer Architecture
The Oracle WebServer is the first Oracle product that allows application developers to
create Web-based interactive applications that work closely with the Oracle database.
At first glance, the architecture of WebServer may seem confusing. Since the Oracle
WebServer is a very powerful product, there are a plethora of ways in which the tool
can be configured and used. However, there are some analogies to existing Oracle
products that may help in conceptualizing the WebServer architecture. For instance, it
is very similar to the architecture of Oracle’s SQL*Net product. A Web listener runs
on the WebServer host, polling for incoming URL requests. As each request is
received, the WebServer directs the request to Oracle, extracting the required data and
preparing an HTML document for transmission to the requesting browser.
Let’s take a look at some of the many ways that WebServer can be implemented.
In its most basic form, a Web server acts as a simple request dispatcher that takes a
URL request (such as http://myhost.domainname:port/ows-bin/owa/
stored_procedure_name) and returns an HTML document to the requester. WebServer
supports this basic task with the added benefit of being able to dynamically create
Web pages from Oracle database information. The primary purpose of Oracle’s
WebServer is to create HTML documents, complete with HTML tags, that contain
literal values extracted from Oracle databases. Using this technology, WebServer can
create customized responses to user requests.
When WebServer receives a request, a Web listener initiates the process by contacting
the Oracle database. From there, the requested procedure is called, translated into an
HTML document, and then returned to the Web browser. While this is a very
simplistic overview, it serves to demonstrate the basic functionality of a WebServer.
Figure 2.1 displays a high-level view of the WebServer’s basic architecture.
• Web Listener
• Common Gateway Interface (CGI)
• Web Request Broker (WRB)
• PL/SQL Agent and WebToolkit
• Java Cartridge
• LiveHTML Cartridge
Let’s take a look at how each of these components work and interact with each other
to provide an Oracle WebServer environment.
Figure 2.2 displays the architecture for Oracle WebServer 1 as it relates to generating
dynamic Web pages via Oracle PL/SQL stored procedures. As you can see, we begin
with a Web browser that is used to specify the URL that identifies the stored
executable procedure. This URL is passed to the Oracle Web Listener, which
determines whether it is a static or dynamic request for a Web page. If the URL
specifies accessing a flat HTML file on a file system, then the Web Listener would
retrieve this file and return it to the browser as a static Web page. In this scenario,
since a PL/SQL procedure was specified in the URL, the Web Listener recognizes this
as a request for a dynamic document and passes the request through the CGI to the
Oracle Web Agent. The Web Agent processes the PL/SQL stored procedure, which is
stored in the Oracle7 database, and generates HTML with dynamic data from the
database. This HTML gets picked up by the Web Listener, which sends it back to the
Web browser as a Web page.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The main difference between versions 1 and 2 of Oracle WebServer is the addition of
the Web Request Broker. In Figure 2.3 you can see the process for dynamic Web page
generation, but this time within the framework of the Oracle WebServer 2 architecture.
Just as before, the URL is entered by a user through a Web browser and is sent to the
Oracle Web Listener. Again, static document requests would be processed by
retrieving HTML from your file system and sending it back to the browser, where it
would be displayed as a static document. For dynamic generation of Web pages
initiated by a request, the user specifies the module to be executed in the URL. The
Oracle WebServer 2 implementation of the Web Request Broker provides several
options for generating dynamic documents, including the PL/SQL Agent (formerly the
Oracle Web Agent), Java, LiveHTML, and custom-built modules. You’ll notice in
Figure 2.3 that in addition to processing a dynamic request through the WRB, it is also
possible to execute the request through CGI. Whether a dynamic request is processed
through the WRB or CGI depends on the virtual directory specified in the URL.
If the user specified the request to be executed through the CGI, then the PL/SQL
Agent would execute the stored procedure and the dynamic HTML generated would
be returned to the browser via the Web Listener. If the URL specified that the WRB be
used as the dynamic interface, then the WRB Dispatcher within the WRB would
spawn a WRBX process to direct the request to the proper cartridge. (In Web
terminology, the term cartridge refers to an additional feature, usually a procedural
language module, that can be plugged into the WebServer architecture. WebServer
published the specifications for their plug-ins so that third-party vendors can create
new cartridges to access Oracle WebServer.) The dynamic content would be retrieved
from the database and sent back to the browser by the Web Listener. The use of the
WRB, instead of the CGI, as the dynamic page generation interface is highly
recommended, since WRB is the better performer due to the establishment of
persistent database connections.
Web Listener
The Web Listener is an HTTP engine on the Oracle host that manages incoming
requests for services. The Web Listener submits incoming requests to the Web
Request Broker for processing. After the HTML page has been built, it is handed back
to the Web Listener. The Web Listener then sends the completed HTML document
back to the originating requester. Each host may have many listener processes running,
depending on the processing needs of the Oracle WebServer. At a minimum, it is best
to have one Listener for DBA tasks, and another for developers to build the
applications and users to access those applications.
The Common Gateway Interface (CGI) enables external applications, such as clickable
image maps and fill-in forms, to interface with information servers. These information
servers (such as Web servers) include Oracle WebServer, NCSA’s HTTPd, and
Netscape’s Communications server. A CGI program is executed in realtime to output
dynamic documents that are flexible in meeting the changing needs of users. This is a
carryover from WebServer 1 technology and is maintained as an alternative for
dynamic page generation to allow compatibility with CGI scripts that were executed in
previous applications. CGI is still a highly utilized interface throughout the Web and
will be around for a long time to come.
The Web Request Broker (WRB) is defined by Oracle as “an asynchronous request
handler with an application program interface (API) that enables it to interface
dynamically and seamlessly to various back-end technologies.” In plain English, the
WRB acts as a handler for Web requests made to Oracle databases. Internally, the
WRB consists of a dispatcher that maintains communications with a pool of processes
called WRB executable engines. These engines, in turn, interface with various WRB
cartridges.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
PL/SQL Agent And WebToolkit
The PL/SQL Agent is a cartridge that allows the Oracle WebServer to execute PL/SQL that resides in Oracle
packages and stored procedures. In addition to executing standard PL/SQL, the PL/SQL Agent can carry calls
to WebServer utilities and HTML functions. For example, we might see the following calls in a PL/SQL
stored procedure:
htp.FormOpen(owa_util.get_owa_service_path || 's10');
This code is calling a procedure in the Oracle WebToolkit called htp.FormOpen, where htp is the name of
an Oracle package, and FormOpen is the name of a stored procedure in the htp package. Within this call, we
see a call to the owa_util package, calling a stored procedure named get_owa_service_path.
Note: The htp package is loaded as part of the WebServer install, and the source code can be viewed
by looking at $ORACLE_HOME/ows2/admin/privhl.sql. This can give you additional insight into how
WebServer translates htp package calls into HTML documents. The OWA utilities package (owa_util)
source code can be found in $ORACLE_HOME/ows2/admin/privutil.sql.
The htp and owa_util packages are an integral part of WebServer, and additional explanation for these
packages can be found later in this book in Chapters 7 and 8.
Let’s walk through a PL/SQL Agent process by starting at the beginning of a WebServer transaction. First,
the URL (for example, http://myhost.domainname:port/ows-bin/owa/stored_procedure_name) calls an Oracle
PL/SQL stored procedure, which is loaded and interpreted at runtime. Any calls to htp and owa packages are
also resolved, and a static HTML document is created with Oracle data hard-coded into the body of the
document.
At this point, you might be curious as to how WebServer can create a standard Web page using Oracle
database information. As you may know, official HTML standards require that all HTML documents follow a
basic format and use accepted tags (more information on HTML can be found in Chapter 3). Let’s use a
simple example to illustrate this concept. Assume that you have a Web page that accepts a customer name and
then displays the details for that customer from your Oracle data base. Listing 2.1 shows what the Oracle code
would look like.
create or replace
procedure s10(host_name_in in varchar2) as
host_name varchar2(20);
ip_address varchar2(20);
cust_name varchar2(20);
os_type varchar2(20);
os_version varchar2(20);
oracle_csi_nbr varchar2(20);
dba_pager_nbr varchar2(20);
cursor c1 is
select
host_name,
ip_address,
cust_name,
os_type,
os_version,
oracle_csi_nbr,
dba_pager_nbr
from host
where host_name = rtrim(host_name_in);
host_rec c1%ROWTYPE;
BEGIN
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's10');
htp.htmlOpen;
htp.headOpen;
htp.title('s10');
open c1;
loop
fetch c1 into host_rec;
EXIT WHEN c1%NOTFOUND;
htp.print('Host Name: ');
htp.FormText(host_name,10,50,host_rec.host_name);
htp.print('Customer_name: ');
htp.FormText(cust_name,10,50,host_rec.cust_name);
htp.nl;
end loop;
close c1;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
This Oracle code accepts a host_name_in parameter and will create the HTML source code shown in Listing
2.2.
Listing 2.2 Sample of HTML source code created by WebServer using Oracle data.
<HTML>
<HEAD>
<TITLE>s10</TITLE>
<H1>Oracle information database</H1>
<H1 ALIGN="C">Host Display</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
Host Name:
<INPUT TYPE="text" NAME="" SIZE="10" MAXLENGTH="50" VALUE="sandbox">
IP address:
<INPUT TYPE="text" NAME="" SIZE="20" MAXLENGTH="50" VALUE="111.111.11.11">
Customer_name:
<INPUT TYPE="text" NAME="" SIZE="10" MAXLENGTH="50" VALUE="STORM">
Operating System:
<INPUT TYPE="text" NAME="" SIZE="10" MAXLENGTH="50" VALUE="Solaris">
Operating System version:
<INPUT TYPE="text" NAME="" SIZE="10" MAXLENGTH="50" VALUE="2.5">
Oracle CSI Number:
<INPUT TYPE="text" NAME="" SIZE="10" MAXLENGTH="50" VALUE="1-23-456-7">
DBA pager number:
<INPUT TYPE="text" NAME="" SIZE="10" MAXLENGTH="50" VALUE="777-7777">
<BR>
</FORM>
</BODY>
</HTML>
Note that the htp.form functions have been replaced with literals that contain the actual values from the
Oracle database. For example
htp.FormText(dba_pager_nbr,10,50,host_rec.dba_pager_nbr);
After WebServer creates a Web page, it routes the page to the requester and then displays the page just like
any other HTML document. Figure 2.4 displays a Web page created using WebServer.
Figure 2.4 A sample Web page created using WebServer and Oracle data.
The real benefit of the Oracle WebServer should now be very clear. Rather than the traditional method of
sending static Web pages, the Oracle WebServer allows developers to dynamically create Web pages based
on data from their Oracle databases. Depending on the values entered by a user of a Web page, WebServer
can access Oracle tables and copy the contents of the data columns into HTML documents for display in Web
browsers.
It is important to note that there are other ways to run WebServer besides using PL/SQL. For example, next
we’ll take a brief look at the popular Java language and see how it is used with Oracle’s WebServer.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Java Interpreter Cartridge
Just like PL/SQL stored procedures, the Java language can be used to access Oracle
and create HTML documents. Java is an interpreted, object-oriented language that has
become very popular as a tool for mapping databases to Web pages. Created by Sun
Microsystems, Java has become immensely popular because of the methods it uses to
manage Web data. Modules of Java code are known as applets. These applets can be
downloaded from the Internet and executed locally on the Web browser, thereby
relieving the server of some of its Web processing burden.
Oracle recommends that you use the Java Interpreter when you want to handle
multimedia operations, interface with “objects” on the Internet, or interact with an OS
file system. For database retrieval, Oracle suggests that the PL/SQL Agent should be
used since it is faster. Consequently, the Java Interpreter should be used for special
tasks, such as spooling reports to a printer or consolidating online images.
In Java, class definitions are created, and these definitions are mated with methods, or
behaviors. Java objects are declared according to their class definitions, and Java
objects are aware of the methods associated with each class definition. In addition,
Java objects are aware of other methods in all class definitions above them in the class
hierarchy (this is called inheritance).
In short, Java is a robust, C++-style, object-oriented language that provides all of the
power of object-orientation programming. However, unlike C++, Java does not
support pointers, and you cannot create linked memory structures like you can in C
and C++. Nonetheless, Java remains a very low-level language, with the natural
consequence of being very difficult to read and write. Some of the major benefits of
using Java within the context of the Oracle WebServer include:
On the surface, it may appear that Java is intended to run only on the client side.
However, Java applets are used heavily on the server side, as well. This is the case
with WebServer applets. To execute Java on the Oracle server, the WRB can be used
to invoke the Java Interpreter, which dynamically compiles and executes the Java
applet, returning the requested information back through the WRB to the Web
Listener. Each PL/SQL package that is to be executed through the Java Interpreter
must have a package wrapper, which is a Java class containing methods to call the
procedures and functions in that package. Oracle WebServer also provides a Java Web
Toolkit, which is a collection of packages and procedures that aid in the creation of
Java applets for Oracle.
LiveHTML Cartridge
The LiveHTML cartridge is used to include dynamic content within static WebServer
Web pages. This content may include static Web pages, other LiveHTML Web pages,
system variables, or scripts to be executed on the server that output HTML.
LiveHTML is also frequently referred to as Server Side Includes (SSI).
Whereas a normal Web page is simply delivered to the Web browser, a LiveHTML
page is parsed by the WebServer. In order to execute a LiveHTML call on your Oracle
server, it is necessary to configure an Oracle Web Listener (through WebServer
Manager) to parse files for LiveHTML. Parsing is a process whereby incoming files
are interrogated, or broken down, to see if they contain LiveHTML code. Just like the
Java Interpreter, the LiveHTML cartridge can execute PL/SQL packages through the
PL/SQL Agent. This added dimension provides more flexible options for building the
best applications to meet your functional needs.
Summary
Now that we’ve taken a look at the high-level architecture of the Oracle WebServer
let’s move on to Chapter 3, which describes the basics of how HTML is used to build
Web pages. Then we’ll move on to Chapter 4, where we’ll take a more detailed look at
the installation process and the functions of each of the WebServer components,
explaining the components, what they do, and how they are installed and utilized.
After we have covered the installation and configuration, we’ll take a look at actual
examples of how Web applications are designed and implemented.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 3
Developing Web Pages Using HTML
While knowledge of HTML is not a prerequisite for using the Oracle WebServer, the
ability to understand how Oracle converts your htp commands into HTML will make
the entire scope of the Oracle WebServer very clear. In addition, Oracle WebServer
provides a “back door” for the developer to enhance the HTML commands that are
generated by WebServer. These back doors are called “cattributes,” and allow the
Oracle developer to add additional parameters to the default HTML that is generated
by Oracle WebServer. The details for cattributes are listed in the chapter on
procedures and functions in Oracle WebServer’s manual. In any case, a good working
knowledge of HTML will assist the Oracle developer in creating exciting Oracle-based
Web pages.
This chapter explores the basics of HTML; it does not pretend to be an exhaustive
coverage of this topic. Rather, this chapter is intended to give the Oracle professional a
high-level understanding of the conceptual foundations of HTML, so that the nature of
the Oracle WebServer will become apparent. For a complete text on HTML
development, see the referenced books at the end of this chapter.
In general terms, a Web page is an online Windows screen. Just like a local Windows
screen, a Web page may contain buttons, scroll bars, and many other Windows
• Text—Plain text, which can appear as basic body text or headings, and can
contain a number of font formatting features.
• Hyperlinks—Linked text or graphics, which when clicked on by the viewer
transfers the user to another section of the current document or to another
document on the Internet.
• Pictures—Images that are displayed on the Web page. Often, pictures on
Web pages are also hyperlinks.
• Video—Movie clips, which are appearing on Web pages more and more
often as digital video technology evolves.
• Audio—Sound clips and background music.
• Oracle database data—Data imported from Oracle databases. The basic
HTML from this chapter will be extended in later chapters to show how Oracle
WebServer is used to attach databases to Web pages.
Web pages are created by embedding HTML tags into text documents. Fortunately,
the extreme popularity of HTML has led to the creation of tools that automatically
generate HTML documents. These tools include Adobe PageMill and Claris. Before
you use an HTML editor, it is a good idea to get a handle on the workings of HTML.
HTML is easy to use and understand, so in this chapter we will discuss the manual
method for creating HTML documents.
<title>
<Title>
<TITLE>
In this book, all HTML tags will be displayed in uppercase for ease of reference. In
HTML, most tag commands become “turned on” when an opening tag is read in the
document and remains turned on until an HTML closing tag terminates the command.
It is a good programming practice with HTML to set a tag to “turned off” when it is no
longer needed. Usually, this is done by adding a slash (/) character immediately before
the tag name, and placing the closing tag at the end of the formatted section. To
illustrate, consider the following example:
Here we see the <TITLE> tag being turned on, then the title text for the document,
and finally, the closing tag </TITLE> indicating the end of the title text. But how do
these tags make their way into a document? In practice, there are many tagging tools
that can be used to take unformatted text and add the HTML tags so that the document
can be displayed on a Web page. Oracle WebServer is one of these products, but
WebServer has the enhanced capability of taking data from an Oracle database,
tagging the data, and displaying it on your Web page. Alternatively, you could simply
type the HTML tags manually into a text or HTML editor.
We must note that HTML, like its cousin SGML, has some basic rules that must be
followed for a document to conform to the HTML rules:
Listing 3.1 illustrates a sample of HTML source code, and Figure 3.1 displays how the
source code displays in a browser.
<HTML>
<HEAD>
<BODY BGCOLOR="#ff0000">
This makes a red background
Here we see that immediately before the <TITLE> tag we see a <HEAD> tag. The
<HEAD> tag says that the following part of the HTML is in the head of the document.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
In addition to text, HTML provides formatting tags for changing background colors and adding
background images. Listing 3.1 displays the use of the background color tag. To add background
colors and images, use the tags shown in Table 3.1.
Headers
Headers are used to separate sections of text on a page. You can control the relative font size of
header text, but all header text is formatted by the browser and appears on its own line. Listing 3.2
shows HTML source code used to create the headings displayed in Figure 3.2.
<HTML>
<HEAD>
<TITLE>This is the document title </TITLE>
</HEAD>
<BODY>
<H1>This is a really big header </H1>
</BODY>
</HTML>
Figure 3.2 shows the relative sizes and positions of HTML headers, as they appear in Netscape.
Page formatting allows the designer to control the physical layout of the Web page. Page
formatting tags include the tags shown in Table 3.2.
Tag Use
<P> Paragraph marker
<BR> Line break
<HR> Horizontal rule line (this tag accepts size, width, and alignment
attributes)
Listing 3.3 illustrates the use of these tags, and the results are shown in Figure 3.3.
Listing 3.3 Sample of HTML source code using page formatting tags.
<HTML>
<HEAD>
<TITLE>This is the document title </TITLE>
</HEAD>
<BODY>
<H1>This is the page formatting tags </H1>
Other basic formatting tags include the Comment and Preformat tags, shown in Table 3.3.
In an HTML document, extra spaces are ignored unless the <PRE> tag is used. The <PRE> tag is
especially useful for aligning the columns in a table of text values. In the example below, we see
that the close for a letter uses the <PRE> tag to retain a specific number of predefined spaces:
<PRE> Sincerely,
Don Burleson
</PRE>
The <PRE> tag is very useful when aligning text on a Web page. For example, it would be very
hard to align checkboxes and radio buttons on a data entry screen without it.
A more common alternative for lining up text is the <TABLE> tag, which can be used to create
columns on a Web page. By defining multiple columns on your Web page, linear data can be
mapped across the columns, filling out the width of the Web page, rather than being displayed as a
very long, left-justified string. Tables are too complicated a subject to cover in this chapter. For
more information on tables, look through some of the books listed at the end of this chapter.
In general, the <PRE> tag displays the text in monotype, where each character is exactly the same
width. This is a very useful feature for displaying things like computer code, which must be aligned
properly. For Oracle WebServer, you can use the htp.preOpen and htp.preClose calls. These are
discussed with examples in Chapter 7, WebServer’s HTP Utilities.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
In addition to standard screen text, it is possible to create and manipulate text lists
using HTML. There are numerous types of lists that can be defined with HTML, and
some of the most common are shown in Table 3.4.
Within each list type, there are subtags that assist with the formatting of each element
of the lists, as shown in Table 3.5. Also, note that unlike most other HTML tags, line
tags within lists do not have any closing tags.
For ordered, or numbered, lists, the TYPE values shown in Table 3.6 apply. Note that
TYPE=1 is the default value.
In Netscape, you can define the bullet types for ordered lists shown in Table 3.7. Note
that this is a Netscape extension only. Unless you add graphics to your bulleted lists,
most other browsers have a designated system for displaying bullets that can be
overridden.
To illustrate the different types of lists and how they appear in Netscape, consider the
HTML code example shown in Listing 3.4. Figure 3.4 displays the source code
displayed in a browser.
<HTML>
<HEAD>
<title>This is the icon title </title>
</HEAD>
<BODY>
<LI> Go shopping.
<LI> Buy groceries.
</OL>
There are several ways that styles can be used within text. Styles can be used to
designate text font and formatting options, such as adding bold, italic, strong,
underlined, or emphasis attributes. Listing 3.5 displays some HTML coding that adds
formatting styles to text. Figure 3.5 displays how the Web page would appear in a
browser.
Listing 3.5 Sample of HTML source code for adding text attributes.
<HTML>
<HEAD>
<TITLE>The basic text fontstyles:</TITLE>
</HEAD>
<BODY>
<BR>
<BR>
<I>Italics</I>
<BR><HR>
<B>Bold</B>
<BR><HR>
<U>Underlined</U>
<BR><HR>
<TT>true type (Used for displaying code)</TT>
<BR><HR>
<EM>emphasis</EM>
<BR><HR>
<STRONG>strong emphasis</STRONG>
<BR>
</BODY>
</HTML>
In addition to the standard character set, several extensions to HTML exist for
displaying characters that are not found on a standard keyboard. Listing 3.6 displays
an HTML code snippet showing the special characters.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Link References
In addition to text, you may embed links to other Web pages, email addresses, or chunks of HTML text. Link
references usually refer to a Uniform Resource Locator (URL). Just about any existing document can be
referenced by its URL address (including local files), and the URL allows Internet addresses to be embedded
within HTML source code for easy hyperlinking by viewers.
• Web pages:
• Gopher sites:
• FTP sites:
• Email:
• Internal references:
Linking Images
Most browsers support two type of image formats: GIF (pronounced “jiff”) and JPEG or JPG (pronounced
“jay-peg”). GIF is CompuServe’s General Interface Format, and JPEG stands for Joint Photographic Experts
Group format. While some browsers support other image types, such as BMP and TIFF, GIF and JPEG are
considered the industry standard for Web page images.
Note: If you already have bitmaps (BMP) or other formatted images, many tools, such as Paint Shop
Pro, can be used to convert your images into GIF or JPEG format.
To reference an image within an HTML document, use the IMG (Image) tag and its accepted parameters to
point to and format an image stored on a server:
<IMG SRC="myfile.gif">
In this example, the code includes a call to the image named myfile.gif. When the HTML document is
viewed in a browser, the myfile.gif graphic will appear on the Web page where the image tag appears in the
HTML document. In addition to the SRC parameter, the ALIGN parameter is a very useful extension within
the IMG tag. The ALIGN tags normally indicate where a graphic will appear in relation to surrounding text.
Note: Among other extensions, the IMG tag can include the sizing parameters WIDTH=n and
HEIGHT=n.
When creating a Web page, it is not enough to simply create a dazzling graphical display. You can turn your
Web page into an interactive document in which you can receive information from your viewers. To do this,
your page can be formatted to solicit input from the viewers of your page, interpret the input and perhaps
query an Oracle database, then return a response to the viewer. It is using a Web page as this type of front end
that truly brings the power of the Internet to your organization.
With HTML, there is an INPUT construct that assists in the task of data entry. The values for INPUT are:
Let’s take a look at a sample data entry screen. Listing 3.7 displays a portion of the HTML source code for
the data entry screen shown in Figure 3.7.
<BR><HR>
Your Name? <INPUT TYPE=text NAME="username" SIZE=20>
Your password?<INPUT TYPE=password NAME="passwd" SIZE=20>
<BR><HR>
<B> What region are you from? </B>
<SELECT NAME="region">
<OPTION>North
<OPTION>South
<OPTION>East
<OPTION>West
</SELECT>
<BR><HR>
<B> What is your gender? </B>
<BR>
<INPUT TYPE=radio NAME="sex" VALUE="female">Female
<BR>
<INPUT TYPE=radio NAME="sex" VALUE="male">Male
<BR>
<INPUT TYPE=radio NAME="sex" VALUE="eunich">Eunich
<BR>
<HR>
<BR><HR>
<B> Choose all databases that apply: </B>
<INPUT TYPE=checkbox NAME="database" VALUE="Oracle">Oracle
<INPUT TYPE=checkbox NAME="database" VALUE="DB2">DB2
<INPUT TYPE=checkbox NAME="database" VALUE="Ontos">Ontos
<INPUT TYPE=checkbox NAME="database" VALUE="FoxPro">FoxPro
<BR><HR>
In Figure 3.7, we see some of the most basic form attributes. They include: text input, pop-up lists, radio
buttons, and checkboxes. Let’s take a quick look at each of these form features.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select
Text Input Area
In the second example, we see an input with TYPE=password. All text typed into this field
will be displayed as stars (*) on the Web page.
A pop-up list is very easy to define in HTML. In Figure 3.7, you can see a pop-up list for
the Region field. Pop-up lists are very useful when a field has a low cardinality; that is, a
small number of values. Chapter 10, Managing WebServer Forms And Security, discusses
how Oracle database fields can be placed into pop-up lists.
Radio Buttons
Radio buttons are used in situations where the user must choose only one of a set of values.
Choosing a radio button always deselects the previously selected values; therefore, it is not
possible to select more than one radio button at a time. Radio buttons are used for mutually
exclusive items such as gender, state of residence, and so on. Figure 3.8 displays radio
buttons.
Checkboxes
Checkboxes, as shown in Figure 3.9, are useful for situations where more than one box may
be checked. Checkboxes are most commonly used in cases where a query states “check all
that apply.”
Now that we have reviewed the basics, we can learn a great deal about the internals of Web
pages by actually displaying the source HTML for a page. A great way to view HTML
source code is to ask your browser to display the source code for Web pages that you view.
This is an excellent way to learn the ins and outs of HTML coding.
For example, if you are using Netscape and you find an interesting Web page, you can
choose View|Document Source to display the Web author’s work. (In Microsoft Internet
Explorer, choose View|Source.) Figures 3.10 and 3.11 display a Web page and its source
coding in Netscape.
As an example, let’s take a look at Oracle Magazine ’s home page, shown in Figure 3.12.
As we can see, this is a very sophisticated page with one large image that is mapped as
buttons. To quickly see how this technique works, we can simply display the source code
for this page, as shown in Figure 3.13.
Figure 3.13 The HTML source code for the Oracle Magazine home page.
Note: It is not plagiarism to look at and understand techniques used in Web page
design. Of course, wholesale copying of code is prohibited, but there is nothing to
prevent a curious scholar from viewing a nice Web page to see how it functions.
Also, as a designer of Web pages, you need to be aware that surfers may look at
your HTML source code, as well. Sloppy or naive HTML can be quickly recognized
in this manner.
Here we see the use of the <IMG> and <HREF> tags to support the image construct. From
here, we can see clues about how this image-based menu was created. It should be noted
that the display of image graphics is not simple, especially with image maps, and a
complete discussion is beyond the scope of this text. Image maps (where the position of the
cursor on the image determines the destination hypertext link) are not easy to create, and
require interrogation of the pixel coordinates to determine the exact position of the cursor.
The Oracle WebServer documentation for image maps (htp.img) is described in detail in
Chapter 7, WebServer’s HTP Utilities, and some simple examples are used to show how
clickable images can be used with Oracle WebServer pages.
When creating HTML documents, keep in mind that many people still use character-based
browsers. This means they cannot view images in your Web pages. However, HTML does
allow text to be placed where an image would have been displayed, as long as the browser
can handle this operation. To specify alternative text for images, use the ALT=n attribute.
For example:
If someone has images turned off, or is using a character-based browser, the word after
ALT will be displayed.
When accessing an HTML document with the Oracle WebServer, you need to check the
WebServer configuration to create a “mapping” for the directory that contains the HTML
documents. (See Figure 3.14.)
Summary
This chapter shows how documents created with HTML are different in appearance from
what we see on the Web. Text editors can be used to create HTML documents, which allow
adding, deleting, or modifying text. Formatting of text is a limited capability of text editors.
The displaying of the Web page is defined by the HTML commands and the interpretation
of these commands by the client Web browser.
Many users also turn off automatic image downloading when they access information on
the Web to improve retrieval speeds. Be aware that not all graphical browsers allow the
ALT attribute to display text if image downloading is turned off.
Now that we have a basic grasp of HTML and how it is used to format the display of a Web
page, let’s move on and take a look at how WebServer and Java can be used with our pages.
HTML References
Database Publishing on the Web & Intranets, by Curt Lang and Jeff Chow, Coriolis Group
Books, 1996.
The New Netscape & HTML Explorer, by Urban A. LeJeune, Coriolis Group Books, 1996.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
CHAPTER 4
Installing And Configuring Oracle WebServer
The Oracle WebServer is an HTTP Internet server that is generally associated with an
Oracle database. The Oracle software allows developers to create Web pages that
contain information that has been extracted from the Oracle database, as well as to
take information from Web pages and place the information into an Oracle database.
WebServer also allows for interfacing with non-Oracle databases using Oracle’s
Common Gateway software.
Once installed, users access the WebServer by specifying a URL via a Web browser
such as Netscape or Internet Explorer. The WebServer can extract information from
several sources, including the operating system file system for static Web pages or
from a database to generate dynamic Web pages at execution. As the data changes in
the database, the dynamic HTML documents will change automatically.
The first step to using WebServer is to run the Oracle installer to place the software on
your server’s file systems. While this can be a lengthy process, this chapter has been
designed to provide a step-by-step overview of the issues that may arise during the
installation of this sophisticated software product.
Table 4.1 shows the minimum system and software requirements for the Oracle
WebServer on a Unix host.
200 MB disk space Web browser that supports forms and tables
64 MB swap space
Attached CD-ROM device
Note: For Oracle DBAs, it is important to note that installing the Oracle
WebServer does not require the relinking of the Oracle software executables.
The WebServer can be installed at any time after the installation of the Oracle
database software.
In addition to WebServer, the host machine must have the following Oracle7 database
products installed:
Preinstallation Tasks
Before beginning the installation process, there are several steps that need to be taken.
To start the preinstall steps, log on as the ‘oracle’ Unix operating system account and
execute the following tasks:
1. Set the permission codes for file creation to umask 022. This setting grants
read (but not write) permission to groups and individual users.
2. Set the following environmental variables:
• ORACLE_HOME—Defines the top-level directories where the Oracle
software is installed. This directory and its subdirectories are created by
the Installer, along with the proper permissions. The ‘oracle’ account
must have read, write, and execute privileges. The Optimal Flexible
Architecture OFA default for this variable in Oracle DBMS 7.3.2.1 is /
mount-point/app/oracle/product/release. This OFA default changed from
the previous versions of the DBMS in that the subdirectories app/oracle
were added to the default in this release. If you want to override this
default for ORACLE_HOME, you must install Patch 2 (Oracle 7.3.2.2).
• ORACLE_SID—The Oracle System Identifier must begin with a letter
and be followed by a number or character. The OFA standard is to keep
the length of the system identifier to four places because some operating
systems have this limitation.
• ORACLE_TERM—Sets the terminal definition resource file variable
that is to be used by the Installer. If this variable is not set, the Installer
uses the setting for the Unix environment variable term and searches for
a matching ORACLE_TERM resource file. This Toolkit 2
environmental variable points to the tk2c${ORACLE_TERM}.res file
under $ORACLE_HOME/rdbms/admin/terminal (tk2c represents the
character toolkit2). An example would be vt100.
• Path—This is the search path for software and must include the
following:
• $ORACLE_HOME/bin (Oracle software)—The directory
where coraenv and oraenv (the scripts that standardize the OS
environment for all users) reside. This location varies by
operating system, with the default directory for Solaris being /var/
opt/bin.
• /bin
• /usr/bin
• /usr/ccs/bin
• C compiler directory (if you are using Pro*C).
• A period (.)—to reference the current directory.
• Make and cc utilities directory—make being the utility to
relink the Oracle executables.
• /usr/ucb in your path (if your setup requires)—Place it at the
end of the path list. Ensure that /usr/ccs/bin is before /usr/ucb in
the path list.
• ows/bin (WebServer 1) or ows2/bin (WebServer 2)
directories—Add to your path if Oracle WebServer is installed
somewhere other than under $ORACLE_HOME.
• TMPDIR—When executables are relinked, space is used in the /tmp
or /var/tmp directories. Ensure that adequate space is available if
relinking is requested through the Installer. If space is not available in
these directories, then TMPDIR can be set to another directory.
Sufficient space for Solaris is about 20 MB. The Oracle WebServer
product does not require relinking to integrate it with the instance.
However, the TMPDIR directory is required to have universal
permissions (chmod 777).
• TWO_TASK—If WebServer will not reside on the database server and
thus will operate in client/server mode, then TWO_TASK must be set to
identify the remote server. Do not set this variable if WebServer and the
database reside on the same server. Also, do not set this variable during
a direct installation (not over a network). It should only be set during
remote installations or during and after configuration of WebServer by a
browser.
Now that the preinstall steps are complete, you are ready to begin the Oracle7 Server/
WebServer install process.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Running The Oracle WebServer Installer
For those who are unaccustomed to running the Oracle installer, there are some tips
that may aid you in the WebServer install:
1. $ su root
2. $ mkdir /cdrom
3. $ mount -r -F hsfs devicename /cdrom
Now that the CD-ROM device has been mounted, you are ready to proceed. The steps
to start the WebServer Installer are as follows:
There are some important generalities related to Oracle WebServer installation that
must be set forth before we get started. Multiple versions of Oracle WebServer may be
installed and running on the same server. WebServer 1 and WebServer 2 may even
coexist in the same directory, but I recommend that you follow the defaults that
maintain the software and files in separate locations. To properly uninstall an earlier
release of Oracle WebServer, the Installer should be used to remove the older release
and then install the new release. Oracle WebServer 2 is fully compatible with earlier
releases of the product, which simplifies the upgrade process and maintains process
integrity.
The Oracle WebServer version 1 product is bundled with the Oracle version 7.3.2.1
software distribution CD-ROM. The installation in this chapter uses this version. You
may also download the software from Oracle’s home site on the Internet. Oracle
WebServer 1 is installed by default with the DBMS software distribution and is placed
in the Unix directories $ORACLE_HOME/bin and $ORACLE_HOME/ows.
Oracle WebServer version 1 components include the Oracle Web Listener (OWL), the
Oracle Web Agent, Developer’s Toolkit, and the database (Oracle7 Server). The OWL
is an HTTP server that directly services static (file-based) Web page requests from any
Web browser. The OWL invokes the Oracle Web Agent if database access requires
generating a dynamic document. There is an Oracle Web Listener process called the
Oracle Web Administrative Server (OWAS), which is used by the Oracle WebServer
Administrator to access the Oracle database using a separate Web Agent service. This
service is referred to as the OWA_DBA service. The default service for the Oracle
Web Agent is the OWA_ DEFAULT_ SERVICE.
Dynamic Web pages requested by users are handled by the Oracle Web Agent
(OWA). The OWA is invoked by the OWL. It then connects to the database (Oracle7
Server), requests the execution of the software program to create the dynamic HTML
document, and transmits the Web page back to the browser. The Oracle7 database can
reside on the same server as the OWL and the OWA, or it can reside on a different
server. The OWL and OWA must reside on the same server.
The Oracle WebServer Developer’s Toolkit assists users in building the software
programs to create dynamic documents in HTML format. Each Web Agent has its own
Developer’s Toolkit procedures. In order for the Web Agent to display the HTML
document, the Web Agent’s userid used to connect to the database must own the
Toolkit procedures, as well as the functions that generate the HTML document.
The last major component of the Oracle WebServer is the Oracle7 Server. The Oracle7
Server stores data in its tables to create dynamic HTML documents.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
Installer Prompts
As you execute the install program, you will be presented with installer prompts that
pertain to the installation of WebServer version 1 with the Oracle 7.3.2.1 Server
distribution. Each prompt is displayed in a pop-up window, and many prompts have
defaults that can be accepted by pressing the Return key.
The first installer screen is the Installation Activity Choice screen. From this screen,
choose the option to Install, Upgrade, or De-Install Software (Figure 4.1).
Note: Do not select the Create/Upgrade Database Objects option. This option
only upgrades database objects—not the software.
In this example, we choose the Install New Product option on the Installation Options
screen. As part of our new product installation, the full software installation is being
installed in a new $ORACLE_HOME directory (Figure 4.2). Of course, as with all
Oracle software, the new WebServer installation will be Optimal Flexible Architecture
(OFA) compliant.
Figure 4.2 The Install New Product choice on the Installation Options screen.
Next, you will be prompted for the mount point of $ORACLE_HOME in the
Installation Options: Mount Point screen (Figure 4.3). Notice that the mount point is
the home directory for the ‘oracle’ Unix account and the setting for $ORACLE_BASE
appends the subdirectories app/oracle to the mount point. The Installer will use your
input for the mount point if your Unix environment variable $ORACLE_BASE is
undefined, but you would probably never want to do this. Remaining compliant with
the OFA standard greatly simplifies administration of the WebServer software.
The Installer prompts for the complete pathname of the $ORACLE_HOME directory,
which it refers to as the Home Locator. The format for the Home Locator is /
mount_point/app/oracle/product/7.3.2. This is the directory base where Oracle
WebServer and all other Oracle software will be installed. Oracle WebServer can be
installed in any directory, but installing it in $ORACLE_HOME will ensure OFA
compliance.
The Installer now inquires whether you want to create a database as part of your
installation. Unless you want to accept standard parameter defaults to create a generic
database, answer “No” and create your own database after the software distribution is
installed to disk.
The Logging and Status screen (Figure 4.4) prompts you for the location of log
information pertaining to the installation. Available logs are shown in Table 4.2.
The Installer will not automatically overwrite these logs if they already exist, but it
will prompt for your choice of disposition. That is, you can either create newly named
log files or append existing logs.
The README.FIRST file is displayed automatically with product updates that might
not have made it into the hard copy documentation before the distribution was released
(Figure 4.5).
The next screen queries if you want to skip the display of the README.FIRST file in
subsequent executions of the Installer. A nice feature of the Installer is that it keeps
track of your responses from session to session. It’s not a bad idea to continue
displaying this file in the future because you may encounter new situations where this
information is more applicable.
On the Install Source Screen, you will indicate whether the installation is from CD-
ROM, tape, or a disk-based staging area. The procedures in this chapter are based on
installing from CD-ROM, but there may be situations where you would download the
software to disk and then install Oracle WebServer from a staging area.
Figure 4.6 displays the NLS (National Language Support) screen to request the
specification of a language for screen messages from Oracle products with NLS
support. You can choose All Languages or one of the displayed languages. The default
language for the Installer happens to be American/English.
Next, the Installer will prompt whether you want to relink the executables or not. No
relinking is necessary for a new install, including Oracle WebServer. However,
because relinking requires additional disk space, you might want to relink now to
determine if you have enough disk space for this process in the future. The default for
this screen is no relinking.
At this point, an Information screen (Figure 4.7) will be displayed stating that the root.
sh script needs to be executed by the root account as a post-installation step. Click on
OK. Executing this script starts the WebServer Administrative Server and updates the /
etc/oratab file with the Oracle SID, the ORACLE_HOME variable setting for this
instance, and whether this instance should be shut down and started up by the dbshut/
dbstart scripts.
Note: Your Unix systems administrator must always be involved to run the
root portion of the WebServer install.
In Figure 4.8, choose whether you want Online Help Installed for all products being
installed, the products of your choice, or no products.
In the Unix Documentation screen now displayed, choose whether you want Unix-
specific documentation installed. In my experience, this documentation has not proven
very useful, so you may want to omit this feature from the installation.
The next screen presented is the Product Documentation Library CD-ROM Install
screen. Use this screen to indicate if you want product documentation installed from
the product documentation CD for all products being installed, the products of your
choice, or no products.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Next, the Software Asset Manager screen (Figure 4.9) is displayed. The Software
Asset Manager is where you choose the products you want installed. It also tracks the
size of the products you choose to be installed and the space available in the target
directory (in this case, $ORACLE_HOME).
Notice that there is no option to choose the Oracle WebServer product to be installed.
It is installed by default with the Oracle7 DBMS, and you must install the Oracle
database in order to install WebServer version 1 from this CD-ROM. If you are
installing online documentation or if you will be viewing the Product Documentation
Library CD-ROM, you will also want to install the Oracle Unix Installer and
Documentation Viewer.
In the Official Hostname screen, enter the hostname and domain of the server on
which you are installing. An example of a hostname would be server.ledger.company.
com.
You are now prompted by the TCP Service Port screen to specify a TCP network port
number for the WebServer Administrative Server. This tool is used to manage the
Oracle Web Listeners (remember, there can be more than one Web Listener, each on a
different port) and Oracle Web Agent. The default port for the WebServer
Administrative Server is 8888, which is okay to select. You can enter this service port
number in the /etc/services file to reserve it for this specific use, but it is not required.
The port number can be between 1024 and 65535. If you choose a port number below
1024, the root privileges will be required to start the listener.
Note: You will receive the error “Address already in use” if you attempt to
start an Oracle Web Listener with a port number that is already in use on that
server by another Listener.
The Password screen is now displayed, which requires the entry of a password for the
WebServer admin user. Initially, the admin user will be the only user allowed to
access the Administrative Server and will be required by your browser during the
configuration of WebServer.
Note: The admin user is an Oracle WebServer user, not an operating system
or an Oracle account user. There is no default setting for the password.
Next, the Verify Password screen will prompt for the admin user password to verify
that the password was entered correctly the first time.
The Installer now displays several screens indicating that the installation of the Oracle
software distribution to disk is proceeding. A screen indicating the installation of
Oracle WebServer 1 libraries is one of these screens. When the Installer completes its
installation tasks, the Software Asset Manager screen will redisplay. Press the Exit
option to close the Installer.
As was previously stated, multiple versions of Oracle WebServer may be installed and
running on the same server, including WebServer 1 and WebServer 2. They may even
coexist in the same directory, but maintaining separate locations is usually a better
way to operate. If you opt to uninstall an earlier release of Oracle WebServer, your
uninstallation should be performed by using the Installer to remove the older release
before installing the new release. Oracle WebServer 2 is fully compatible with earlier
releases of the product, ensuring its future viability and making our job a little easier.
request requires the use of a Service. A Service can be accessed through the Web
Request Broker (WRB) (WebServer 2 only), an executable of a CGI interface, or a file
system on the same server as the Listener. The last two access methods are available in
either WebServer 1 or 2. If the WRB is needed to satisfy the request, the Listener
sends the request to the WRB Dispatcher to be processed. There is a group of
processes called WRB Executable Engines (WRBXs) that are used by the WRB
Dispatcher to manage requests. Each WRBX links to an application called a WRB
cartridge with the WRB API. A WRB Service is the combination of one cartridge with
the WRB API. Some of the WRB Services supported by Oracle WebServer 2 include:
To ensure that we can proceed with the installation by using the Oracle Installer, use
the following steps:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
These are the Installer prompts that pertain to the installation of WebServer 2 from the
Oracle WebServer 2 CD-ROM. Each prompt is displayed in a pop-up window and
many prompts have defaults that can be accepted by hitting the Return key.
The first Installer screen is the Installation Activity Choice screen. Here we choose the
option to Install, Upgrade, or De-Install Software (Figure 4.10).
Note: Do not select the Create/Upgrade Database Objects option at this point.
This option only upgrades database objects —not the software.
In our example, we have chosen the Install New Product option on the Installation
Options screen because WebServer 2 is being installed into the $ORACLE_HOME
directory as part of an existing product installation (Figure 4.11). The installation will
be OFA compliant.
Select the Add/Upgrade Software option on the second Installation Options screen to
install the Oracle WebServer 2 software into an existing Oracle7 ORACLE_HOME
directory (Figure 4.12).
The Installer now prompts for the complete pathname for the $ORACLE_HOME
directory, which it refers to as the Home Locator (Figure 4.13). The format for the
Home Locator is /mount_point/app/oracle/product/7.3.2. This is the directory base
where Oracle WebServer will be installed. Oracle WebServer can be installed in any
directory, but installing it in $ORACLE_HOME is strongly recommended, and will
ensure OFA compliance.
The Logging and Status screen (Figure 4.14) prompts for the storage location of log
information pertaining to the installation, including the files shown earlier in Table 4.2.
The Installer will not automatically overwrite these logs if they already exist, but will
prompt for your choice of disposition. In other words, you can choose to either create
new logs or append existing logs.
Figure 4.15 displays the NLS (National Language Support) screen to request the
specification of a language for screen messages from Oracle products with NLS
support. You can choose All Languages or one of the displayed languages. The default
language for the Installer is American/English.
A prompt will appear regarding the root.sh file that contains tasks related to the root
account. It is better to have a new root.sh file created instead of appending tasks from
the current distribution to tasks from the old distribution (Figure 4.16).
The next screen defines the pathname for the file root.sh. The location for this file
defaults to $ORACLE_HOME/orainst.
An Information screen (Figure 4.17) will be displayed stating that the root.sh script
needs to be executed by the root account as a post-installation step. Click on OK.
Executing this script starts the WebServer Administrative Server and updates the /etc/
oratab file with the Oracle SID, the ORACLE_HOME variable setting for this
instance, and whether this instance should be shut down and started up by the dbshut/
dbstart scripts.
Figure 4.18 displays the Online Help Load screen, where you can choose whether you
want Online Help Installed for all products being installed, the products of your
choice, or no products.
See Figure 4.19 for the Product Documentation Library CD-ROM Install screen.
Indicate whether you want product documentation installed from the product
documentation CD-ROM for all products being installed, the products of your choice,
or no products.
The Software Asset Manager screen is now displayed. The Software Asset Manager is
where you choose the products you want installed. It also tracks the size of the
products you choose to be installed and the space available in the target directory
($ORACLE_HOME). In this example, we chose Oracle WebServer 2 on the product
list (which is the only product listed).
Note: If you are installing online documentation or if you will be viewing the
Product Documentation Library CD-ROM, also install the Oracle Unix
Installer and Documentation Viewer.
A Trial License screen is displayed for your consideration, as shown in Figure 4.20, if
you are using Oracle WebServer 2 on a trial basis.
Enter the hostname and domain of the server on which you are installing on the
Official Hostname screen. An example would be server.ledger.company.com.
You are now prompted by the TCP Service Port screen (Figure 4.21) to specify a TCP
network port number for the WebServer Administrative Server. This tool is used to
manage the Oracle Web Listener(s) and Oracle Web Agent. The default port for the
WebServer Administrative Server is 8888, which is an acceptable default. You may
enter this service port number in the /etc/services file to reserve it for this specific use,
but this is not required (this file is informational only and does not enforce its content).
The port number can be between 1024 and 65535. If you choose a port number below
1024, the root privileges will be required to start the listener.
Note: If you attempt to start an Oracle Web Listener using a port number that
is already used by another Listener on the same server, then you will receive
the error message “Address already in use.”
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select Next you’ll see the Password screen, which requires the entry of a password for the
WebServer admin user. Initially, the admin user will be the only user allowed to
access the Administrative Server and will be required by your browser during the
configuration of Oracle WebServer. The admin user is an Oracle WebServer user, not
an operating system or an Oracle account user. Note that there is no default setting for
the password.
Next, the Verify Password screen prompts for the admin user password to verify the
previously entered password.
The Installer now displays several screens indicating that the Installation of the Oracle
software distribution to disk is proceeding. A screen indicating the installation of
Oracle WebServer 2 libraries, shown in Figure 4.22, is one of those screens.
An Information screen indicates that the root.sh script needs to be executed by the root
account after the installation. Running this script will start the Administrative Server
and allow you to use a browser to access the URL and configure Oracle WebServer.
Another screen indicates that Oracle WebServer 2 is being registered (Figure 4.23).
When the Installer completes its tasks, the Software Asset Manager screen will
redisplay. Click on the Exit option to close the Installer.
Once the Oracle WebServer executables and files have been installed to disk, then you
must configure the software. You can begin this process by making sure that there is
connectivity to the Oracle7 database server that will be accessed by the Oracle Web
Listener. This is accomplished by pinging the server (including the domain name) at
the Unix level. An example would be ping hostname.domainname, which will return a
message stating whether or not the server is alive. If the Web Listener is on a different
server than the database, then SQL*Net will have to be installed and configured. In
our example, the configuration is based on the Oracle Web Listener and Oracle7
database residing on the same server.
Once connectivity has been verified, then you must start a Web browser. In our
examples, we use Netscape Navigator as the browser for configuration. In Netscape’s
address box, specify the URL to connect to the Oracle WebServer Administrative
Server using the http://hostname. domainname:port/ows-abin/register format, as shown
in Figure 4.24. The hostname.domainname signifies the server where the Oracle
WebServer Administrative Server is running. The port is the TCP/IP port chosen
during Installation that will allow connection to the Oracle WebServer Administrative
Server.
Figure 4.24 Specify the URL to the Oracle WebServer Administrative Server.
You will then be prompted for the username and password for the WebServer
Administrator (Figure 4.25). This WebServer userid will be used to execute the
functions of the Oracle WebServer Administrative Server. During the installation of
Oracle WebServer 1, the userid was identified as admin.
Figure 4.25 Enter the username and password for the WebServer Administrator.
The next screen displayed is the Oracle WebServer Product Registration page (Figure
4.26). In this screen, you should complete the information requested and click on Send
Registration to register your use of the Oracle WebServer 1 product. After you submit
the registration form, you will be presented with the WebServer Install form.
On the first section of the WebServer Install Form (Figures 4.27 and 4.28), click to
configure the OWA_DBA (Oracle Web Agent DBA) service. The requested input
includes:
Figure 4.27 The first page of the Oracle WebServer Install form.
Click on the Create Service button, which creates the OWA_DBA service. The Unix
file $ORACLE_HOME/ows/admin/owa.cfg will now contain an entry for this service.
Figure 4.29 displays the successful creation of the OWA_DBA service.
Now we can configure the initial Oracle Web Listener through the WebServer Install
Form (Figure 4.30). The configuration is done by providing:
Figure 4.30 The Oracle WebServer Install form—Oracle Web Listener screen.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select The next step is to start the first Oracle Web Listener by clicking on the Create
Listener button. To review configuration information for the Oracle Web Listener on a
Unix system, see the file $ORACLE_HOME/ows/admin/sv PORT .cfg (PORT is the
TCP/IP port number chosen for the Oracle Web Listener). A screen displaying a
message for the successful creation of the Oracle Web Listener is then displayed.
The next few screens enable you to choose the configuration of the
OWA_DEFAULT_SERVICE for performing non-DBA functions, such as creating
your applications. The inputs for this screen are similar to those for the OWA_DBA
service. Click on the Create Service button after entering your inputs to create the
service. The successful configuration of the OWA_DEFAULT_SERVICE is displayed
in Figure 4.31.
You have now completed creating the three services and have a basic configuration of
Oracle WebServer 1. To proceed to the Oracle WebServer Product home page (Figure
4.32), you should click the hyperlink on the Install form, which will lead to the Web
pages where you can administer the Oracle7 database, Oracle Web Listeners, and
Oracle Web Agents. Figure 4.33 displays the Oracle WebServer Administration page.
The Oracle WebServer Administration page allows for the management of the Oracle7
databases, Oracle Web Listeners, Oracle Web Agents, and the Web Request Broker.
At this point, you can shut down and start up the instances and OWLs, and modify the
configurations of the OWLs and OWAS. From the Administration page you can
choose to administer the Oracle Web Agents. Web Agent administration would
include creating new Web Agent services and modifying or deleting an existing
service. Additional pages exist for the other functions on the Oracle WebServer
Administration page.
Note: The Oracle Web Listener can be stopped and started through two
different methods depending on the Listener. The OWL for the Administrative
Server that performs the DBA functions can only be stopped and started
through the following Unix-level command:
For WebServer 1:
wlctl8888 stop
wlctl8888 start
For WebServer 2:
The non-DBA OWL can be stopped and started through the use of the same
command or through the OWL Administrative page.
Once the Oracle WebServer 2 executables and files have been installed to disk, then
you must configure the product software. You can begin this process by making sure
that there is connectivity to the Oracle7 database server that will be accessed by the
Oracle Web Listener. This is accomplished by pinging the server (including the
domain name) at the Unix level. An example would be ping hostname.domainname,
which will return a message stating whether or not the server is alive. If the Web
Listener is on a different server than the database, then SQL*Net will have to be
installed and configured. The configuration in this chapter is based on the Oracle Web
Listener and Oracle7 database residing on the same server.
When connectivity is established, then you may start a Web browser. The following
procedures utilize Netscape as the browser for configuration. In Netscape’s address
box, specify the URL to connect to the Oracle WebServer Installation Page using the
http://hostname.domainname:port/ows-abin/boot format.
Note: You will receive the error “Address already in use” if you attempt to
start an Oracle Web Listener with a port number that is already in use by
another Listener on the server.
You will then be prompted for the username and password for the WebServer
Administrator (Figure 4.34). This WebServer userid will be used to execute the
functions of the Oracle WebServer Administrative Server. During the installation of
Oracle WebServer 2, the userid was identified as admin.
Figure 4.34 Specify the username and password of the WebServer Administrator.
The Oracle WebServer Administrative Server (OWAS) is the Oracle Web Listener
that you are currently connected to. This Listener has more privileges on the database
than other Listeners that manage queries against the database. The WebServer
Installation Page (Figure 4.35), provides the following input areas to create the first
Web Listener for non-DBA tasks (application-privileged):
services file, it would be a good idea to avoid future contention for that port by
at least reserving the port in this log. The valid range of port numbers is
between 1 and 65535.
• Unix User ID—Used to run the Oracle Web Listener. This should be a low-
privileged user, such as the Unix nobody account, which exists by default on
many Unix systems. CGI programs executed by the Listener will acquire the
same privileges as the Unix account (and its group) that is running the Listener.
• Unix Group ID—Accessed by the Listener User ID. A good group name
would be webdba. Make sure this group is created by the system administrator
and that the nobody user-privileged account is assigned to it. Using a User ID
in the Unix DBA group will pass DBA privileges to all who use this Listener,
including those who are creating and executing CGI programs.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select Start the first Oracle Web Listener by clicking on the Create Listener button. To
review configuration information for the Oracle Web Listener on a Unix system, see
the file $ORACLE_HOME/ows2/admin/svOWLname.cfg (OWLname is the name of
the Oracle Web Listener). Figure 4.36 displays the successful creation of the Oracle
Web Listener.
The next section of the WebServer Installation Page deals with creating Database
Connection Descriptors (DCDs). DCDs are required before you can connect to a
database. DCDs supply information to the PL/SQL Agent, including which Oracle
userid to use for connection and which database to connect to. There can be multiple
DCDs created per database (and multiple Listeners). A suggestion would be to create
one DCD for each application in a database. The database accessed by a DCD can be
shared by multiple WebServers on different servers. Click to configure the
OWA_DBA DCD (Figure 4.37), which will be used by the Administrative Server for
DBA tasks against the database. The requested input includes:
• Username and password—For the Oracle account that the DCD will use in
Click on the Create Service button, which creates the OWA_DBA DCD. The Unix file
$ORACLE_HOME/ows2/admin/owa.cfg will now contain an entry for this service.
The next few screens enable you to choose the OWA_DEFAULT_SERVICE DCD
used for performing non-DBA functions (by application-privileged Listeners) such as
creating your applications. The screen inputs are similar to those for the OWA_DBA
DCD creation. In providing input for the creation of the OWA_DEFAULT_SERVICE
DCD, the port number must be entered and should be different from the number used
by the OWA_DBA DCD. Click on the Create Service button to create the service.
You have now completed creating the Oracle Web Listeners and DCD services and
have a basic configuration of Oracle WebServer 2. When you would like to administer
Oracle WebServer, click the hyperlink on the Oracle WebServer Installation Page to
proceed to the Oracle WebServer Administration home page (Figure 4.38).
Please Select
Populating The Oracle Dictionary
After completing the basic installation, you will need to populate the Oracle dictionary
with the OWA and HTP packages and procedures. The source code for the packages
and procedures is located in $ORACLE_HOME/ows2/admin as owains.sql, and this
code will update the dictionary. To run the dictionary update, enter svrmgrl, then enter
the code shown in Listing 4.1.
Listing 4.1 Populating the OWA and HTP Oracle dictionary packages.
Now that the dictionary is populated, you will need to configure the WebServer to use
PL/SQL stored procedures to generate Web pages. There is a checkbox in the DCD
Create and DCD Modification screens for installing the PL/SQL Developer’s Toolkit
(Figure 4.39). Checking this box will grant the necessary Connect and Resource
privileges to the OWA database user, and installs all of the PL/SQL Web Toolkit
packages (using the SQL in the file $ORACLE_HOME/ows2/admin/owains.sql). The
packages created in the OWA_DBA PL/SQL Agent account are prefaced with OWA_
and HTP. HTP packages must have Public synonyms created for them and Execute
privileges granted to Public.
When you have multiple DCDs defined, the following steps should be performed:
1. If the PL/SQL toolkit has already been installed on multiple DCDs, choose
one installation to be the “master” install and drop the following definitions
from all other schemas. Remember that the package owa_parms is not included
with Oracle WebServer 2.0.x, but is included with version 2.1 and greater. You
can still get this script from a WebServer 2.1 CD-ROM (or download from
http://www.oracle.com), and use it with your Oracle WebServer 2.0
installation. The owa_parms package is used to facilitate the updating of
database tables:
• connect schemaowner/password
• drop package htf
• drop package htp
• drop package owa
• drop package owa_util
• drop package owa_pattern
• drop package owa_parms
• drop package owa_text
• drop package owa_image
• drop package owa_cookie
• drop package owa_init
The owner of the original install of the PL/SQL Toolkit will become the
Toolkit owner.
2. Grant execute privileges against each of the following packages to all of the
schema_owners from Step 1:
• grant execute on htf to &&1
• grant execute on htp to &&1
• grant execute on owa to &&1
• grant execute on owa_util to &&1
• grant execute on owa_pattern to &&1
You should now have everything necessary to create a sample Web page and execute
it using your Web browser.
The best way to test your newly installed WebServer is to install and run the Oracle
WebServer demo. This is an interactive set of Web pages that simulates a travel
agency for train travel. It is also a great way to familiarize yourself with the internals
of Java, images, and other WebServer features. To install this demo, follow these steps:
1. Optionally, you can create a new DCD through the WebServer Manager. I
used my existing OWA_DBA DCD. New DCDs can be created through the PL/
SQL Agent Administration page via WebServer Manager.
2. Reconfigure your Oracle Web Listener to set up the proper directory
mappings where the train application will reside. The virtual directory name /tr-
img must be created that maps to the physical directory $ORACLE_HOME/
ows2/demo/img. This is accomplished through the Oracle Web Listener
Administration page by clicking on the Configure hypertext link and
proceeding to the directory mappings link.
3. Install the database objects for the application by connecting to
ServerManager line mode (svrmgrl) as the Oracle account corresponding to the
DCD. Execute the script $ORACLE_HOME/ows2/demo/demoins.sql. If you
are re-executing this script, then you must run the script demodrop.sql first.
4. Because you updated the directory mappings, the Oracle Web Listener
needs to be stopped and started via the Oracle Web Listener Administration
page. This process will reload the configuration file with the updates to make
them effective.
5. Execute the demo by accessing http://hostname:port/demo/owa/tr.splash or
by clicking on the “Taking the Train” image on the Oracle WebServer
Administration page.
6. View the log for this application in $ORACLE_HOME/ows2/log.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Testing Your Install
If you have successfully run the Oracle train demo, you can now test WebServer’s ability to write and
execute WebServer code from within an Oracle stored procedure. To test stored procedure access, add
the stored procedure shown in Listing 4.2 to the dictionary using the same schema_owner that added
the owa packages.
create or replace
package hello as
procedure world;
end;
/
show errors
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
This will create a package called hello that contains a stored procedure called world. The procedure
world contains various calls to htp functions that were added when you ran owains.sql. Once this
package has been added to the dictionary, it can be executed from your Web browser at http://hostname:
port_number/ows-bin/owa/hello.world. Upon invoking this URL in your Web browser, your screen
should display as shown in Figure 4.40.
For example, your URL call might look like http://hostname:8888/ows-bin/owa/hello.world, where:
As we know, the Web Listener is an HTTP engine on the Oracle host that manages incoming requests
for services. The Web Listener sends incoming requests to the Web Request Broker, which, in turn,
passes the request to the PL/SQL agent. Once the HTML page has been built, the Web Listener sends
completed HTML documents back to the requesting browser. Each host may have many listener
processes running, depending upon the processing needs of the Oracle WebServer.
There are two ways to service requests: through CGI or WRB. The Web Listener decides whether to
direct an incoming request to either function depending on how the directory mappings are defined and
which directories are specified in the URL. Base directory mappings for both execution paths are
defined by default during installation and configuration of the Oracle WebServer.
Note: Oracle recommends using WRB as the access method; it is faster and more efficient than
the CGI. Originally, the CGI interface was the only access method for WebServer, introduced in
version 1, but it is now considered the lesser of the two.
Processing scripts through CGI requires that virtual directories be defined through the Web Listener
Administrative Page for the physical location of the scripts (PL/SQL, Perl, Java), whether they be on
disk or stored as PL/SQL procedures in the database. These virtual mappings are configured by first
accessing the Oracle Web Listener Administrative Page through the WebServer Manager, as shown in
Figure 4.41. Next, click on the CONFIGURE hyperlink, which will transfer you to the Web Listener
Configuration page (Figure 4.42). On the Web Listener Configuration page, click on the configuration
parameter Directory Mappings to display the fields for defining the virtual and physical directory
mappings (Figure 4.43). When these parameters have been entered, click on the Modify Listener button
to update the configuration file. In order to make these updates effective, the Oracle Web Listener must
be stopped and started from the Listener home page. In this example, one mapping is for the execution
of PL/SQL procedures via the virtual directory /ows-bin/owa. The owa string tells the Listener to use
the PL/SQL Agent for processing and, in this case, through the CGI. An example of the URL you
would specify to execute a stored procedure through this CGI configuration is:
http://server.domain:port/ows-bin/owa/procedurename
Figure 4.43 Defining the CGI directory mappings on the OWL Configuration page.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select Configuring The Web Request Broker For Processing Requests
Configuring the WRB to process scripts requires that virtual directories be defined
through the Web Request Broker Administrative Page for the physical location of the
scripts, whether they be on disk or stored as PL/SQL procedures in the database. These
virtual mappings are performed by first accessing the Oracle Web Request Broker
Administrative page, as shown in Figure 4.44, through the WebServer Manager.
Clicking on the Modify hyperlink will transfer you to the Web Request Broker
Configuration page (Figure 4.45) where you will define the virtual and physical
directory mappings. When these parameters have been entered, click on the Modify
WRB Configuration button to update the configuration file. In order to make these
updates effective, the Oracle Web Listener must be stopped and started from the
Listener home page. In this example, one mapping is for the execution of PL/SQL
procedures via the virtual directory /tr/owa. The owa string tells the Listener to use the
PL/SQL Agent for processing and, in this situation, through the WRB. An example of
the URL you would specify to execute a stored procedure through this WRB
configuration is:
http://server.domain:port/tr/owa/procedurename.
Figure 4.45 Defining the WRB directory mappings on the WRB Configuration page.
If you encounter technical difficulties in your installation, you can call Oracle for
technical support. In addition, you might also want to email a description of your
problem to Oracle. WebServer support has an email address just for technical
problems: [email protected].
Summary
If you successfully got hello.world to display, you can be confident that your
WebServer installation is complete. Next, we’ll take an in-depth look at Managing
WebServer Applications in relation to Oracle’s WebServer technology.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 5
Designing WebServer Applications
The phenomenal explosion of Web-based access to worldwide information has fueled
the interest in interfacing Oracle databases with Web front ends. Most industry
analysts agree that the Web is much more than just a passing fad, and that the future of
database management lies in a company’s ability to deliver Web front ends for their
applications. Most likely, within the next decade, Web-based front ends will be used in
every area of information systems, from the end user who wants to see her checking-
account balance to the employee who accesses his intranet to see his current work
assignments. During the next few years, we will continue to see a great explosion of
Internet usage. Advances in communications speed will soon make video display
practical on the Web, and full-screen videos will soon become commonplace for
applications ranging from instruction videos to product advertisements. The exciting
part is that, unlike traditional display environments, Web pages allow hypermedia
linking with other Web sites anywhere in the world—all at the click of a button. Web
access also dramatically changes the way textual information is delivered to end users.
Powerful concept-based search engines, such as ConQuest, Fulcrum, and Folio, have
cleared the path for Web publishers to deliver text from Oracle databases at a low cost
and with fast, accurate results. Unlike traditional publishing in books or CD-ROMs,
text delivered with Oracle WebServer will be cheap to produce and instantly available
to anyone on the globe.
The Web as a delivery framework for Oracle information has also recently improved.
With the availability of Oracle’s WebServer and HTML frames (see the section htp.
frame in Chapter 7, WebServer’s HTP Utilities), a Web page can display several
independent Oracle data windows, and each window on the Web page can be
refreshed without having to retransmit the entire Web page.
Unlike a development effort that uses PowerBuilder or SQL*Forms for the front end,
Web-based Oracle development requires the participation of developers with new skill
sets. These people may include visual designers, commercial artists, and systems
engineers. For example, the use of an image map (a large, single image used as a
menu) requires sophisticated artistic design for the image, while a systems engineer
may be required to write the code to interrogate the mouse clicks and transfer control
to the target page. If your Oracle application requires the end user to print or download
information, you will need systems programmers experienced with Java and
LiveHTML to create interfaces between your Web pages with Web clients.
Another unique feature of WebServer applications is that you can track the usage of
your application in far greater detail than you can with PowerBuilder or SQL*Forms.
The Oracle WebServer provides several detailed logs that can be used to track
information such as the number of times clients access each Web page, and the
computer platform and IP address of each client. WebServer log analysis will be
discussed in detail later in this chapter.
Line Speed
The single most important factor in remote Web page access is communications speed.
Your end user may be accessing your WebServer application through a superhigh-
speed T3 connection or via a 14.4 Kbps modem (Table 5.1).
As you may know, the graphical capabilities of Web pages make it impractical for
anyone with less than a 14.4 Kbps modem to access Web pages, and even at 14.4
Kbps, it requires the patience of a saint to wait while large GIF or JPEG images
display on the Web page. Even a small image may take more than three minutes to
display on a 14.4 Kbps modem. However, the problem of slow image display will
probably be solved as technology improves. If we see the same advances in speed and
data compression that we have in previous years, we can expect that these constraints
will soon evaporate. As line speeds continue to increase, we will almost certainly see
increased demand for online video clips (VID files) and virtual reality environments
(VRML).
Note: Virtual reality is now being used in some Web pages. For ysome
excellent examples of VRML Web pages, visit http://qtvr2.quicktime.apple.
com and http://www.pathfinder.com/twep/rome.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Note: With WebServer 3.0 and the advent of Developer/2000 for Oracle, new
uses have been found for the execution of Java applets on the client.
The speed of the remote client is one of the foremost considerations when determining
whether to process locally on the client. For example, a client accessing your
WebServer application using a T3 line and an HP-9000 will receive an almost
instantaneous response, while a user with a 14.4 Kbps modem and a 386 PC might
wait five minutes to display your Web page. Consequently, careful consideration
needs to be given to the expected client platforms. In practice, in-house intranet
WebServer applications might have dazzling Java animated images, while Oracle
applications designed for the public may have fewer image maps and Java applets. But
we must always keep in mind that the end user has some control over the amount of
local processing. A savvy end user may choose to configure their Web browser to
bypass images and turn off Java, or they may configure their browser not to accept
cookies from your WebServer. Hence, the application designer must always consider
the lowest common denominator when designing Oracle Web applications for public
consumption.
One of the most commonly used client processing applications is done with cookie
files. A cookie is generally a small flat file that is stored on a specific spot on the
client’s disk drive. By having the Web application store information on each client’s
disk, the server is relieved of the burden of storing end user–specific information about
each client session. For example, a cookie could be used to store the most recently
viewed customer record or to an end-user’s usage preferences. For more information
about using cookies, see Chapter 7, WebServer’s HTP Utilities.
Another subtle difference can be seen in the manner in which a Web browser displays
a Web page. A page displayed on a Solaris Unix using Netscape may appear slightly
different than the same page running Netscape on a PC platform. These differences are
most apparent when displaying interactive Web forms that allow the end user to enter
information to interact with Oracle.
Another problem that arises when writing Web pages for a variety of client platforms
involves fonts. HTML supports standard fonts and font sizing, but many Web
browsers enable users to locally configure Web page font and font size settings. For
example, the statement
htp.header(1,'Hello world.');
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select This statement will display a level 1 heading, but the heading may display in a Times-
Roman font on one platform and an Arial font on another. To confuse matters further,
most Web browsers allow the user to change the default font type and font size. For
example in Figure 5.1, we see a Web page using Netscape’s default fonts, and in
Figure 5.2 we see the same HTML document with the Netscape font settings
configured locally.
Figure 5.1 A Web page displayed with standard Netscape font preferences.
Figure 5.2 A Web page displayed with user-defined Netscape font preferences.
Text alignment is another issue in Web page design. HTML documents always default
as left-justified. However, the designer can easily specify a different alignment in their
code using <TEXT ALIGN=>. Also, the HTML 3.2 standard allows Web page
designers to use the <TABLE> tag to align column data. It is important to use tables
when aligning text, because if the end user changes his or her Netscape display
preferences, data columns may fail to align properly. Figure 5.3 shows how a data
input form defines for full-page display, while Figure 5.4 shows the same form after
the orientation has been changed.
Figure 5.4 A standard data input form after changing the browser orientation.
One common solution to text alignment is to utilize the HTML <PRE> tag. <PRE> is
used to display preformatted text on the Web page. By default, the <PRE> tag uses
monotype, so it can be very effective in displaying uniform Web pages across client
platforms and browser orientations.
Those who were Oracle developers in the 1980s may remember how the advent of
Microsoft Windows introduced new design issues. The process of designing Windows-
based front ends for Oracle database applications is very different than designing for a
24×80 fixed-screen display. The addition of Windows’ Graphical User Interface (GUI)
constructs brought a host of new widgets previously unknown to the Oracle developer.
These widgets included:
Early efforts from mainframe developers at using these widgets to develop online
Windows applications were both humorous and disturbing. Checkboxes were used
where radio buttons were appropriate, text was shrunk into incomprehensibly tiny font
sizes, and the misuse of Windows controls made some applications very difficult to
understand. It wasn’t until the general acceptance of the Windows Standard
Development Kit (SDK) that generally acceptable usage was adopted for Windows
widgets.
Today, the development of WebServer pages also presents new features, and the new
Web features have just as much potential for misuse as the new Windows widgets in
the 1980s. The introduction of the World Wide Web has brought new widgets and
screen constructs previously unknown to MS-Windows experts. Knowledge of these
features and of their uses is critical to the delivery of WebServer applications. The new
Web widgets and features include:
In a Web page there are none of the cumbersome chores involved in mapping out
repeating groups of data. Unlike a one-page display screen, such as a SQL*Forms or
PowerBuilder screen, a Web page will display all of the repeating values on a single
document. Since the entire Web page is in a single document, the Web page will allow
the end user to use the scroll keys to traverse through the text of the Web page. From a
developer’s perspective, this approach is beneficial, because each “repeating” list of
data items does not have an array subscript to manage. For example, a repeating list of
customer names will not be subscripted customer_name(1), customer_name(2), and
so on. Since HTML documents do not support these arrays, the Oracle developer must
come up with a method for uniquely referencing these repeating values within their
WebServer application.
Browser Display
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 Eart
ITKnowledge
Please Select
Web Frames
A frame is an internal window within a Web page. Using frames, multiple HTML documents
can be simultaneously viewed and manipulated from within a single Web browser window.
When using frames, changing a value within one frame may cause different information to
display in the other page frames. For example, consider Figure 5.5 where the value of the
customer ID field determines the contents of three separate frames on the Web page. Each
frame can be scrolled independently of each other, providing complete access to all of the
requested information. Each time a new customer ID is chosen, the contents of the other page
frames are updated to reflect the choice. Each frame is refreshed independently of other frames
on the Web page, so frames can greatly improve the performance of your WebServer
application.
Note: For details on using frames with WebServer, see htp.frame in Chapter 7,
WebServer’s HTP Utilities.
Another popular use for frames is for Web page Help functions. When help is requested, a
frame appears in a portion of the Web page, and the Help frame can be manipulated
independently from the other frames on the page. Frames are also popular when designing a
custom search engine for your Oracle database. One frame could accept the search command,
another frame could display the results of the search, and the remaining frames would not
change.
Note: The concept of frames was new with Netscape version 2.0. Not all Web
browsers support frames, therefore a special tag called <NOFRAMES> is used on
many HTML documents so that non–frame-enabled browsers will still be able to
access Web pages containing frames. When defining frames, it is important to note that
any URL on the Internet can be added to a frame. Frames can also display output from
Java applets. Frames can also be nested, or placed within other frames. Each of these
frames, in turn, contains the URL to other Web pages, which can also be composed of
frames.
The tags <FRAMESET> and <FRAME> are used within an HTML document to define
frame windows. The <FRAMESET> tag is used to define the number of frames and frame
sizes. Following are some examples of <FRAMESET> and <FRAME> tags:
In the examples, the first HTML tag would create three vertical rows that are 100 pixels deep.
The second tag would creates three columns that are 25 pixels wide. The last tag specifies the
HTML document that will reside in the frame and the scrolling options for the HTML
document. The <FRAME> and <FRAMESET> tags are used within HTML documents and
htp.frame defines a frame for an Oracle WebServer page.
Web Tables
Tables are used as a formatting tool for Web pages to control the spatial positioning of
information. Netscape was the first browser to offer table capabilities, and tables are easy tools
to use to create well-formatted WebServer pages. Today, any browser that supports HTML 3.0
and above will support the definition of tables.
A Web page table can be thought of as a visual representation of an Oracle table. The
difference being, that while an Oracle table must contain column values, an HTML table may
contain text, graphics, or images.
Prior to the introduction of tables, formatting Web pages was very labor-intensive. As we
know, text and images on a Web page are left-justified by default and (if no alignment
attributes are assigned) concatenate into one very long single-column Web page. With the
introduction of tables, designers can control text and images across the entire Web page.
Tables can be used in a variety of ways to control the layout of information. For example,
consider Figure 5.6. This Web page uses tables to control the display of sports scores.
Figure 5.6 A sample use of HTML tables in a data display Web page.
In addition to column formatting, tables are useful within Oracle WebServer to design data
input forms. Information gathered from Oracle tables can be formatted with borders and
Note: For more information on the use of tables for designing Oracle tables, see htp.
Table functions in Chapter 7, WebServer’s HTP Utilities.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Just as the old-fashioned Personal Function (PF) keys were used within an SQL*Forms
application to transfer control to another screen, hyperlinks are used within a WebServer
application to transfer control to another Web page. However, there are several important
differences between the traditional method of screen transfer and those afforded by the use of
hypertext links in WebServer:
• A hyperlink can be used to transfer to any Web page, anywhere on the Internet. As
such, links outside your WebServer application are now very easy to create.
Unfortunately, transferring back from an external Web page may be impossible unless
the end user is directed to use the Web browser buttons to return to your WebServer
application. Of course, hyperlinks to pages outside your WebServer screen domain
should be carefully controlled.
• While hyperlinks may be made to pass parameters to the target Web page, database
currencies are not easily passed between pages. Consequently, maintaining your place
in your Oracle database depends upon careful programmatic solutions. See Chapter
11, WebServer Navigation And Concurrency Management, for more information on
controlling Oracle currency and database access.
• Most Net browsers feature buttons at the top of the window, as well as menu
commands, allowing end users to browse backward and forward (see Figure 5.7).
These browser buttons allow the end users to bypass any flow control mechanisms
that you may have designed into your architecture.
Figure 5.7 The Netscape Back and Forward buttons and menu commands.
Unfortunately, hyperlinks are one of the easiest Web mechanisms to implement. This is
unfortunate because of the widespread misuse of hyperlinking in many Web-based
applications. Complex application systems generally must have a well-defined flow of
control between screens, but hyperlinks are commonly overused to the point where it is very
easy for your end user to become “lost in cyberspace” (see Figure 5.8).
Unlike traditional Personal Function keys for transferring application control, a WebServer
application may use several different methods for allowing the end user to transfer to another
WebServer page. Table 5.2 summarizes the possible ways that hyperlinks can be
implemented.
There are a variety of methods used for transferring control to another Web page, so it needs
to be clear to the end user that the widget does indeed transfer control. This is not always self-
evident because push buttons and hyperlinks can be given misleading names.
Unlike traditional applications, end-user preferences and selections from Web pages can be
used to create customized screens. Remember, the main purpose of Oracle WebServer is to
create dynamic Web pages where Oracle table data is embedded into an HTML document,
viewed by end users. One of the natural consequences of this powerful feature is that Oracle
WebServer applications may customize entire pages according to the preferences of
individual end users. In fact, end users could customize their pages to the point that it may
not become apparent that two end users are accessing the same application! In any case, the
power of WebServer to create user-customizable pages is very impressive, but again, there is
potential for abuse.
It could be argued that all Web pages are dynamically generated from Oracle because Oracle
data is embedded into the HTML at runtime. However, dynamic page generation in this
context refers to the ability of the WebServer application to customize most of the Web page
attributes, including:
• Frame contents
• Background wallpaper and colors
• Table formatting
Care should be taken when using dynamic page generation because the application logic can
become very cumbersome. To illustrate, consider the following example.
For our example, assume that a Web-based Oracle application is designed to serve as a
vehicle for placing orders for a mail-order warehouse. Developers want to target
advertisements and specials according to customer demographics. Consequently, there are
two profiles for end-user customers. One profile is comprised of customers whose previous
purchases are for items with an average cost of less than $100 (ordinary customers), while
the other profile is comprised of customers whose previous purchases are for items with cost
averages more than $100 (big_spender customers). As users identify themselves to the
WebServer application, internal logic classifies each customer, and the display is configured
according to the customer’s profile. For marketing purposes, a billboard image may be
defined within the Web page to display a customized advertising image, just as a billboard
might advertise products in a storefront. In addition, big_spender customers might receive
an image message offering a discount on expensive jewelry, while ordinary customers will
receive an image offering discounts on less expensive household items. Listing 5.1 shows
how a PL/SQL stored procedure could be used to classify a customer.
select avg(item_price)
from
line_item, item, order
where
order.customer_id = :cust_id
and
order.customer_id = line_item.customer_id
and
line_item.item_nbr = item.item_nbr;
BEGIN
open c1;
fetch c1 into average_price;
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Now that the boolean value of big_spender and ordinary customers has been set, the
WebServer application can test this value to determine the appropriate images and
frames to place on the dynamic Web page. This type of application has the benefit of
being encapsulated in the sense that a single Web page (corresponding to a single
Oracle stored procedure) controls all the logic involved in the display of the Web page.
There will be a single procedure governing the display of the Web page for all
customer profiles, although the processing logic in the PL/SQL may become rather
complex.
The alternative is to design two Web pages, one for each customer profile. This
involves redundant coding of the common characteristics of the Web page but has the
benefit of isolating each profile into an independent stored procedure. In any case, the
ability to dynamically model Web pages is a very powerful feature of Oracle’s
WebServer, and it is a feature that requires careful up-front planning.
The use of clickable images to transfer control within Web applications has become
almost a de facto programming standard on the World Wide Web. Instead of
presenting your end user with a main menu that consists of push buttons, it has
become customary to hire a graphic artist to create beautiful images that serve as
menus for Web-based systems.
It should become apparent that the use of clickable images is a powerful tool for drill-
down menus in a WebServer application, but this power does not come without a cost.
Using Oracle WebServer, it is very easy to invoke the htp.Image procedure to create a
clickable image. The htp.Image procedure will track the coordinates of the end user’s
mouse as they scan the image, and it will pass the row and column pixel coordinates to
a transfer routine when the image is clicked. This is the easy part! The programming
challenge comes into play when the receiving Web page accepts the row and column
pixel coordinates and uses them to decide which Web page should be invoked. Note in
Figure 5.9 that the pixel coordinates are displayed at the bottom of the browser screen,
after the question mark. These row and column pixel coordinates will be sent to the
receiving routine (in this example, omihome.map) to determine which page will be
accessed next.
Figure 5.9 The Web page for Oracle Magazine with a clickable image map.
Images, when used properly, can create a very pleasant front end for an Oracle
database application. Vendors are rushing to meet the demand for images by
producing CD-ROMs packed with GIF and JPEG images. It is also very easy to
capture an image from any Web page. For example, using Netscape, simply place your
mouse over the image and hold down the right-hand mouse button (see Figure 5.10). A
menu will appear allowing the local capture of the GIF or JPEG image.
Note: While it is very easy to capture an image that you find on the Internet,
you should be aware that many images are protected by copyright.
Consequently, it is important to get the written permission of the owner of the
image before using the image on a Web page.
By now, it should be apparent that designing an Oracle application for use with a Web
page front end is very different from traditional application design. This section will
explore the major design issues involved when creating Oracle WebServer
applications and will describe how the knowledgeable Oracle developer can create
effective and credible Oracle systems while exploiting the power of Web-based
documents.
There are many opinions about the most effective methods for designing application
front ends, and there are also many opinions about the proper procedures for creating
Web pages. Old-timers may remember when application design involved using a
cumbersome IBM product called Basic Mapping System (BMS). With BMS, all rows
and columns had to be carefully mapped onto a fixed 24-row by 80-column screen,
and it was not uncommon for an experienced developer to spend an entire day
formatting an online display screen. This is a far cry from today’s technology, where
many children in elementary school are able to create ad hoc Web pages with very
little up-front design effort.
Today, screen layouts can be easily created and prototyped in minutes, and changes
can be tried online almost as fast as the developer can click the mouse. This ease of
screen definition has led to a change in attitude about online systems design. Today,
the generally accepted method for screen design involves an iterative process whereby
the developer successively refines the screen design until the most appropriate screen
image has been agreed upon by the end-user community. While this approach is fine
for small departmental systems, the development of large Oracle systems requires
more forethought, especially when the front end is designed for a Web page. Also, the
scope of Web page access is greater than any online systems designers could
comprehend, and it is impossible to solicit complete screen preferences from the entire
end-user community.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Fortunately, an approach for the design of Web front ends is very simple and
straightforward. Just as with traditional online systems, online design for WebServer
applications should follow a top-down approach, where basic goals are defined and
successive refinement exposes the application details. The main difference between
traditional systems analysis and Web-page systems analysis lies in the determination of
when to stop departitioning the functions. For example, whereas a traditional online screen
may be able to have 50 separate online screens, the performance limitations of mapping out
Web pages may dictate that only 10 Web pages are used, with frames defined within the 10
Web pages to handle additional functionality.
The principles of top-down analysis tell us to begin our data flow diagram (DFD) at a very
general level. The entire system is viewed as a single process called the Context Level DFD.
The DFD is then decomposed, adding levels of detail to the model. The pivotal question
becomes, “Where does one stop decomposing the processes?” Any process that could be
identified can probably be subdivided to smaller processes, and it is possible to decompose
a DFD to the level where each process represents a single statement. An extreme example
of functional decomposition would be showing the statement ADD 1 TO COUNTER as a
separate process on the data flow diagram.
Just as with traditional systems design, the DFD should be decomposed to the Functional
Primitive level, where each process bubble performs one granular function. Under this
definition, one could consider that the place_an_order behavior performs only one
function and is therefore a functional primitive process. When designing for WebServer, the
level of decomposition should correspond to a table operation so that each behavior
operates on only one object within the Oracle database. This allows the use of triggers
within Oracle and greatly simplifies the systems design. In our example, an insert trigger is
placed on the ORDER table. This trigger checks the INVENTORY table for items’ in-
stock levels and also checks the CUSTOMER table for the customer credit rating.
Figure 5.11 shows a level 1 Data Flow Diagram (DFD) for a customer process. In this
diagram, we see that the basic function of the Web page is for an online customer to place
an order. As part of this process, three Oracle tables are accessed. We must check the
INVENTORY table to ensure that adequate stock is on hand, we must access the
CUSTOMER table to ensure that the customer possesses a proper credit rating, and we
must update the ORDER table to reflect the placing of the order.
While our Web page may have only a single page for the place_order process, it is clear
that there will be a good amount of Oracle activity within this page. For object-oriented
relational databases, it is better to continue to decompose the place_order behavior into its
subprocesses, namely check_credit, add_order, check_inventory_level,
decrement_inventory, and add_line_item. These are all subprocesses within the
place_order behavior, as shown in Listing 5.2.
place_order (
check_credit(SELECT on CUSTOMER)
add_order(INSERT on ORDER)
check_inventory_level(SELECT on ITEM)
decrement_inventory(UPDATE on ITEM)
add_line_item(INSERT on LINE_ITEM)
)
To see the complete details for this Web page, further refinement of the DFD is required as
shown in Figure 5.12. Here we see that the place_order process has been departitioned into
three subprocesses, and the data flow between each is described.
If we assume that this is the lowest-level DFD, then how will these processes map to our
Web pages? This is the crux of the issue, and one that requires an intimate knowledge of
each process. After all, the real point of systems analysis is to make the developer intimate
with the logical processes so that they can better understand how these logical processes are
mapped into physical Web pages.
Now that we have completed the systems analysis for the Web page, we are free to look
into the screen design issues as they apply to our WebServer application. Of course,
systems design is very different from systems analysis. Whereas systems analysis
determines the processes and interaction with the Oracle tables, the systems design process
is intended to determine which processes will have Web pages and how the Web pages will
interact with one another. Special attention needs to be given to the needs of the Web front
end, and we need to ensure that our WebServer application is simply defined, following
intuitive navigation rules. Once the overall framework for the WebServer application has
been designed, the next step is to create task flow diagrams. A task flow diagram is a
technique where the processes required to complete a specific task are listed and the screen
layouts are associated with the tasks. Consider Listing 5.3 for our customer-order system.
Place an order:
Enter customer information
accept customer name
accept customer shipping address
accept customer telephone number
accept customer shipping mode
accept customer payment method
Enter order information
for each item
accept product ID
validate product ID
accept quantity desired
check inventory levels
if not sufficient_stock_on_hand invoke backorder page
end
Complete order form
Compute order total
Verify customer credit
If bad_credit invoke COD page
Submit order
adjust inventory levels
create packing list
display customer shipping information
It should be clear that the process of placing an order is quite involved, and this process will
have a great deal of activity against our Oracle database. Now that we have listed the major
tasks and their goals, we need to associate these tasks with the appropriate Web pages. This
begins the systems design process.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
There are two major design issues that need to be addressed at this stage. The foremost
consideration is the determination of the hierarchy of Web pages for the application. In
WebServer applications, as with all online applications, the systems designer must be
cognizant of the number of pages the system will contain. An application can be built
very flat as seen in Figure 5.13, where the home page transfers to only one level of
subpages.
On the other hand, Figure 5.14 shows how a WebServer application can be designed
with many levels of pages. Some online systems designers might argue that this is a
better design approach because each individual Web page performs a finite function.
While these levels of pages more clearly describe the individual operations within the
online system, there may be problems with this vertical approach to the creation of
Web pages.
Because the application will be residing on the Web, you need to take into account
several factors. First, you should determine whether it is necessary for each process to
reside on its own Web page or whether HTML frames could be used to create
subpages within a flatter page structure. Remember, the more complex the navigation
pathway in your Oracle WebServer application, the more opportunities for procedural
error. Also, a vertical Web page design makes it more difficult for the end user to keep
track of her position within the Web page hierarchy.
One of the primary goals of preliminary Web page design is to create a clear
framework for end users so they know where they can go within a cyberspace domain.
To illustrate this concept, consider the hierarchy of Web pages for our fictional mail-
order company. The home page consists primarily of a logon screen and a menu that
directs end users to a table of contents for the various product categories. The next
major function of this system allows the end user to peruse the products, as well as
invoke a procedure to order products at any time. Logon screens are especially
important when granting access to Oracle databases. To ensure WebServer security,
we must gather the end user’s Oracle ID and password, and ensure that we always
keep track of our end user as they transfer between Web pages. Remember, we do not
have the luxury of opening a single connection with Oracle and holding that
connection for the entire duration of their session. Instead, we must develop a method
for using pseudoconversational processing with Oracle role-based security to ensure
that we always maintain accurate connections with Oracle on an as-needed basis.
In addition, we document common Web pages that may be invoked at any time from
any Web page. Just as the F1 key in Windows can always be used to invoke a Help
page, we need to create a framework where our end user can get access to our common
functions. These common functions include:
Notice that “anywhere” access to these Web pages poses an interesting design
problem. If an end user invokes the Help facility (probably with a hyperlink), we need
to be able to pass to the facility the context of their help request. This will certainly
include the name of the page they were on when they invoked the help facility, and
may also contain information about the status of the task they were currently in the
process of completing. Once having viewed Help, we must ensure that our end user
returns to the proper place in their application without having lost any salient
information.
While this may seem self-evident, it is not an easy task to freeze an Oracle transaction,
transfer to another Web page, and then return to the proper position. While this issue is
discussed in depth in Chapter 10, Managing WebServer Forms And Security, suffice it
to say that this type of functionality requires detailed forethought from the designer.
End users love predictability, and many developers make the design mistake of
creating systems that are too flexible and nonrigid for their end users. This trap is
especially true when designing Web page front ends for applications. One of the
cardinal rules for application developers has been “force the end user to follow your
rules.” As designers, we must have a mechanism to enforce which screens end users
see, which buttons they can use, and the format of all incoming data. It is also
tempting for many designers to fail to involve the end users in this stage of design.
Remember “the primacy of the user” principle. No matter how elegant and well-
designed your system may be, the alienation of end users from the development of the
front end will often lead to disgruntled end users—even if the design is perfect for
their needs. End users like to feel involved in the design process whenever possible,
even if the developer does not address all of their requests.
Now that you have an overall feel for how WebServer analysis and design is different
from traditional analysis and design, let’s take a look at the logging features of
Oracle’s WebServer.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
Using Audit Logs With Oracle WebServer
One of the nicest features of using WebServer is the useful logs that are created. Any time a URL request is
received by the Web Listener, entries are made into the logs, and these logs contain some very useful auditing
and usage information. WebServer logs are located on the WebServer host in the $ORACLE_HOME/ows2/
log directory. The following logs are found in this directory:
• owa_default_service.err—An error log that is very useful for debugging WebServer applications.
This log contains:
• Date-time stamp
• ORACLE WEBSERVER error number and message
• ORACLE error number and message
• PL/SQL error number and message
• OWA service name
• Procedure name where the error was encountered
• svadmin.log—This is the server administration log for recording all WebServer requests. This log
contains:
• WebServer server_name
• Date-time stamp
• Type of GET request
• syserr.log—Records system errors
• sv8880n.log—Records all incoming requests for the port number (in this example, 8880 is the port
number). This log contains:
• IP address of the requesting client
• Date-time stamp
• Type of GET request
Because the WebServer logs are kept in ordinary flat files, it is very easy to write programs to show Web
page usage by categories of users, as well as tracking individual users. Listing 5.4 shows a sample from the
owa_default_service.err log. Here we see that the call to the procedure called s10 contained the wrong
number of arguments. Note that this problem can be avoided by defining all stored procedure input values
with a default value of NULL.
The owa_default_service.err log is especially useful for debugging WebServer code. For example, if the URL
for a WebServer stored procedure specifies three parameters, while the stored procedure is created to accept
four parameters, an error message will be written to this log. You can easily track error messages in the
WebServer log by adding the following alias command to your Unix logon script:
When testing WebServer applications, it is good practice to have a Unix window open, so that when you
encounter a WebServer error, you can use the log alias to quickly diagnose the cause of the problem.
Note: The WebServer log suffers from the same limitations as the Oracle alert log. The WebServer
logs are stored as Unix flat files, which will continue to grow indefinitely until they are purged or
archived by the WebMaster. In general, it is usually a good idea to “roll-over” the WebServer logs on a
periodic basis. For example, the Unix remove command (rm) could be put into a cron task to discard
the log contents, followed by the Unix touch command to re-create the log. Another possibility is to
archive the WebServer logs to tape using the TAR or CPIO utilities.
For example, a Unix shell script could be written to count the number of times a particular Web page is
requested. In most cases, each Oracle Web page is stored as a separate stored procedure. Listing 5.5 shows a
very simple c shell script that will scan the directory where the Oracle stored procedures are kept (assuming
that the Unix filenames are the same as the stored procedure names) and produces a count for the number of
times that the stored procedure was called by WebServer.
Note: In Oracle, it is a good practice to give descriptive names to the Unix files that contain the source
code for your Oracle stored procedures. For example, the stored procedure with the Oracle name
add_customer may be stored in a Unix file called add_customer.sql. If you do not keep your stored
procedures in a flat file with the same name as the stored procedures, we could easily enhance the script
to read the stored procedure names from the Oracle data dictionary with the SQL command select
distinct name from dba_source where type = ‘PROCEDURE’.
Listing 5.5 A c shell program to count the number of requests for a WebServer page.
#! /bin/csh
foreach inst ('ls $DBA/source/procedures |cut -d"." -f1')
echo The Web page named $inst was requested 'grep $inst sv8880n.log|wc
-l' times
end
In Listing 5.5, the Unix script simply loops through each procedure name and extracts a count for the number
of times each procedure was called by the Oracle WebServer. Listing 5.6 is the output from running the script
in Listing 5.5. This provides a very useful measure of the number of times that each Web page was called.
Listing 5.6 The output from the c shell program to count the number of requests for a WebServer page.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
With Oracle WebServer 3.0, a new log server is available. The WebServer 3.0 log
server includes the following features:
In addition, WebServer 3.0 offers a log analyzer tool. This tool will read the
WebServer logs and produce graphical reports. The log analyzer allows the generation
of reports based on URL addresses, number of times Web pages are accessed, client IP
addresses, and other log statistics.
Summary
Now that we have reviewed the basics of WebServer design, we are ready to explore
the details of Oracle’s WebServer. The upcoming chapters will cover Oracle’s
common gateway interface, the HTP and OWA functions, and detailed information
and examples from working WebServer applications. We will then take a look at Web
forms management within a WebServer application, navigation between Web pages,
and performance and tuning considerations for Oracle WebServer.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 6
Oracle’s Common Gateway Interface
Communication between Web servers and the databases that provide Web browsers
with dynamic information is facilitated by an executable program called a gateway
interface. The Common Gateway Interface (CGI) is one of the oldest and most widely
used gateway interfaces, but Oracle has developed a better implementation of the
process called the Web Request Broker (WRB). This chapter discusses CGI as a basis
for the WRB technology, because the WRB function processes parameters using the
same environment variables as CGI.
Origins Of CGI
Web servers have always been able to present static documents without the assistance
of other programs. However, dynamic content, user input, and database interface
cannot be accomplished by static documents; dynamic documents need to be used. In
actuality, dynamic documents have been around a long time, and have been written in
several programming languages. This was made possible by the simplicity of the
original HTTP specifications handling the requests.
Over time, Web servers have become more complicated and it became apparent that it
was not practical to replicate certain functions for every application requiring dynamic
documents (such as logging, communications, security, and load management). So
Web server developers began to provide interfaces that could execute external
The CGI standard was designed to provide a method for interfacing a database with
Web pages. Originally initiated by Rob McCool of the National Center for
Supercomputing Applications (NCSA), the early development of CGI was done in the
Perl language by Tony Sanders of Berkeley Software Design Incorporated. Credit also
needs to be given to Charles Henrich of Michigan State University. Henrich developed
a way for Unix servers to incorporate parsed HTML features, which built the
foundation for creating dynamic HTML documents.
Components Of CGI
Many of us are familiar with the HTML documents that lie behind the pages we have
retrieved on the Web. These can be viewed by choosing View|Document Source in
Netscape, or a similar command in most other Web browsers. The HTML documents
and the information they contain are static in that they do not change. Static documents
are good when you want to precisely control what users can and cannot do with a Web
page. On the other hand, if you want Web pages with clickable image maps and fill-in
forms that interface with information servers such as Oracle WebServer, NCSA’s
HTTPd, and Netscape’s Communications Server, then you’ll want to use an interface
such as CGI.
CGI programs are executed in realtime as a means to output dynamic documents that
are flexible in meeting the changing needs of users. To access a database from the
World Wide Web using CGI, the page’s URL needs to be specified as input for the
CGI program. When a viewer sends the URL to the server, the CGI program executes
and identifies the user’s request. The request is then sent to the database engine for
processing, and the results are sent back to the server and then relayed to the viewer’s
browser. A common use of CGI programming is to have a Web client use a CGI
search program to submit search criteria, perform the search, and return an index or
document to the requesting client.
Allowing anyone to run a CGI program on your system presents a security risk that
needs to be addressed. Unlike standard URLs, CGI programs must reside in a standard
directory so that the Web server will know to execute a program rather than display a
static page (such as an HTML document) on the requester’s browser.
Programming Languages
• C or C++
• Perl
• OraPerl
• FORTRAN
• TCL
• All Unix shells (C shell, Bourne shell, Korn shell)
• AppleScript
• Visual Basic
Note: OraPerl is a version of Perl that has been extended through the
Iusersubs feature to allow access to Oracle databases. Using the usub
mechanism (see the usub/ subdirectory in the distribution tree) allows the
linking of a database library allowing embedded calls to Oracle.
Deciding on the coding language to use for a CGI program is an individual choice.
You should base your choice on the software already installed on your system, the
experience of the programming staff, and the functionality that you wish to utilize. The
listed CGI gateway programs vary dramatically in availability and developer
friendliness, depending on the operating system of your server. For instance, Unix
allows easy shell and Perl scripting as well as C coding, whereas Macintosh does not
permit shell scripts to be used, so AppleScript is your only choice.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
CGI uses environment variables to send a program or script its parameters. The CGI standard provides the external
program with information about the server, the browser, and the user. The main environment variables are
query_string and path_info.query_string is represented by whatever follows the first question mark (?) in the URL,
and contains the parameters passed to the PL/SQL procedure. This parameter is only used in the GET form method of
passing information as input.
For example, the following URL executes a program called “entry,” with a query_string of customer=IBM:
http://www.oracle.com:8888/ows-bin/owa/entry?customer=IBM
This information could be added by an HTML GET form or by an ISINDEX document. This string gets encoded in
the standard URL format, replacing special characters with %xx hexadecimal and changing spaces to +. In order to use
this URL, it must be decoded.
path_info allows for extra information to be embedded within the URL for your gateway to send to the CGI program.
This extra information does not get encoded. A very good use for path_info is to send file locations to the CGI
program. Adding extra path information to the end of the URL will tell the CGI program the relative location of the
file to execute. In the below example, the path_info variable would be the string “/entry,” which is the name of the
CGI program (or PL/SQL procedure):
http://www.oracle.com:8888/ows-bin/owa/entry?customer=IBM
The actual path of the file to be executed is defined by the path_translated environment variable that is generated by
the server. The path_translated variable is the full-path directory name pointing to the location of the program on the
server. In the following example, the path_translated variable mapped to the service “/ows-bin/owa” would be “/u01/
dba/oracle/app/oracle/product/7.3.2/ows2/bin”:
http://www.oracle.com:8888/ows-bin/owa/entry?customer=IBM
The service “/ows-bin/owa” is comprised of the Oracle virtual directory mapping “/ows-bin/” and the PL/SQL Agent
executable “owa.”
Client Documents
Once you have retrieved the results from the Web server, you need to send the information back to the client in the
form of a document. CGI programs can return documents of various types, including HTML, plain text, image, audio,
video, and references to other documents. The Multipurpose Internet Mail Extension (MIME) protocol defines several
content types and subtypes that allow programs to recognize different kinds of files and handle them in the appropriate
way. The MIME protocol specifies the type of file, such as video or audio, and the subtype indicates the format of the
file. The Oracle Web Listener recognizes MIME types by the file name extensions (which are case sensitive) and
interacts with the CGI program to inform the client of the document type it will receive. Regardless of whether it is a
full document or a reference to another document, CGI will request users to place an ASCII-text header on the output.
This header is comprised of lines separated by either carriage returns or line feeds (or both) followed by a single blank
line. The output body then follows the header and can be a full or reference document.
The full document output type is communicated to the server through a MIME type. Some examples of MIME types
are text/plain (ASCII only) and text/html (for HTML documents). Listing 6.1 and Figure 6.1 show a sample CGI script
outputting an HTML document for a client.
Content-type: text/html
<HTML> <HEAD>
<TITLE> CGI script outputting HTML </TITLE>
</HEAD> <BODY>
<H1> Organization Members </H1>
</BODY> </HTML>
The reference document output type tells the browser where to retrieve the document or can output the document
automatically (see Listing 6.2 and Figure 6.2). In this example, the document becomes a hypertext link with the anchor
tag (<A>) allowing the definition of the hypertext reference (HREF).
Note: You may not even see the HTML text in a reference document, since many of the newer browsers will
take you to the new location automatically. When referencing another file that does not enforce access
authentication, you only need to specify a partial URL (exclusive of the server name) such as:
Location: /directoryA/directoryB/test.html
Referencing a document that enforces authentication requires the full URL to be specified:
Location: /server/directoryA/directoryB/test.html
Content-type: text/html
Location: http://www.iis-sports.com/sportweb/football/buffalo.html
<HTML> <HEAD>
<TITLE> It's not here anymore </TITLE>
</HEAD> <BODY>
<H1> It moved to another location </H1>
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Most CGI programs are associated with HTML forms and image maps, and serve to
process the results of input (the data input to the form or the spot clicked on the image
map). Image maps are similar to forms and are activated by clicking on a portion of an
image. The specific location of where a user clicks on an image is sent to the server to
determine the information that is to be sent back to the user.
Listing 6.3 shows the HTML source code for the image map. Image maps are
comprised of three parts: the image, HTML coding to specify the image map areas,
called hotspots, and the MAP document. The clickable image map would display a
picture of the state of New York as a GIF image and show the cities where we
maintain our database servers.
<CENTER>
<IMG SRC="header-ny.gif"> <BR>
<A HREF="http://picsite.com/nys.map">
</CENTER>
Coordinates in our sample image are set for Buffalo, Rochester, and Syracuse.
Clicking within the assigned coordinates will call a URL that will transfer the user to a
page displaying information about the database server residing in the selected city.
You can specify the shape of the hotspot to be a circle, square, rectangle, point, or
polygon. These coordinates are stored in the MAP file on the host server and will
define the active points on the image.
MAP files are formatted differently depending on the Web server being used on the
host server. Listing 6.4 displays a sample MAP file, including the coordinates for each
of the hotspots shown on the map. As you can see from the code, clicking within the
defined 30-pixel radius for a specific city will transfer you to that URL. Clicking in the
image map outside of those defined rectangles will default to the URL general.html. If
you are not interested in creating the ISMAP data files manually, there are tools
available to automate the process for you.
default http://picsite.com/general.html
rect (35,40) 30 buffalo.html
rect (56,142) 30 rochester.html
rect (70,167) 30 syracuse.html
Another extension to HTML are forms. Forms allow users to submit input to the host
server. There are a few basic HTML forms, including GET and POST. In
combination with HTML forms, CGI scripts execute on the Web server, where they
receive and process the input sent by users.
The HTML opening and closing tags that define a form are <FORM ACTION=URL
METHOD=METHOD> and </FORM>. The URL specifies the location of the
application script or program that will process the form input, while METHOD
displays as either GET or POST. The GET form can only process small amounts of
input attached to a URL. This input, which follows a question mark, is appended to the
URL, which is then given to the CGI program or script and returned to the Web server.
Using a POST form allows the processing of greater amounts of information because
the form sends data as a data stream using standard input (stdin), not as a long URL.
Your Web page forms can contain any standard HTML tags, as well as some other
tags developed specifically for forms. Some of the form tags for input include:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select
CGI And Oracle’s Web Request Broker
Now that you’ve been presented an overview of the basics of CGI, let’s turn to the
Oracle WebServer 2 architecture and see how CGI fits into WebServer. Oracle
WebServer has the capability of processing dynamic HTTP requests through the CGI.
However, Oracle has also developed their own gateway interface called the Web
Request Broker (discussed in Chapter 2), so both options are available. Further details
on the differences between these two gateway interfaces are described later in this
chapter.
An important part of Oracle WebServer is the PL/SQL Agent. The Oracle PL/SQL
Agent (formerly known as Oracle Web Agent) provides a standard way for Web
clients to invoke Oracle7 stored procedures and create dynamic HTML documents in
realtime. The PL/SQL Agent is a procedural gateway that provides an object-oriented
and extensible mechanism for producing HTML pages using PL/SQL. PL/SQL is
Oracle’s procedural-language extension to SQL and is portable to all operating
systems compatible with the Oracle DBMS.
Another part of the Oracle WebServer puzzle is the Web Request Broker, which is an
asynchronous request handler with an application program interface (API). The API
allows the WRB to interface to back-end software called WRB cartridges. The PL/
SQL Agent is one of these cartridges.
Another component of the WebServer is the Oracle Web Listener (OWL). The OWL
passes incoming URLs to CGI programs or WRB cartridges. When OWL is working
with CGI, it sends the CGI program requests via standard input, and CGI returns
output back to the OWL via standard output. The OWL then sends the output to the
browser on the client. Each time the OWL receives a URL request to run a CGI
program, it starts a separate process to perform the request.
The OWL’s process with WRB is different from its process with CGI, in that WRB
eliminates the need to create a new process for every request. When the OWL
interfaces with WRB, it is free to receive and evaluate incoming URLs while each
request is given to the WRB to execute the desired process in the background. For
example, with the WRB, the PL/SQL Agent would stay connected to the Oracle7
DBMS for all requests, thus avoiding a new connection to the database every time a
stored procedure is executed. This continual state of connection is called persistence.
Persistent connections are what makes WRB a faster process than CGI. Because CGI
lacks persistence, server resources are wasted as users are continually re-identified.
Persistence is also very important for databases to ensure that transactions are either
fully committed or rolled back if necessary. If the connection from browser to
database does not stay open and a transaction must roll back, a new transaction must
be triggered to complete the operation.
Note: If the URL for a request contains the string “owa” in a standard
position, the Oracle Web Listener executes the request using the PL/SQL
Agent. Whether this is done through the WRB or through CGI depends on
how the directory mappings are configured through the Oracle WebServer
Administrator and which virtual directories are specified in the URLs. The
OWL can communicate with either the WRB or CGI through standard CGI
environment variables.
The Webmaster
The Webmaster is the title applied to the person who is responsible for maintaining
your Web server. The Webmaster is usually responsible for the CGI directory and
should implement restrictions on users. These restrictions involve the creation and
execution of CGI programs that assign user privileges. These programs are executed
by a Unix userid on the HTTP server and should, therefore, offer a range of limited
Unix account privileges. For example, in the Oracle WebServer configuration, a low-
privileged Unix user account is called nobody. The nobody Unix user has the
necessary privileges to execute CGI programs, but cannot perform DBA-level
functions against the database.
Summary
Access across the World Wide Web has been greatly enhanced by the development of
interfaces such as the WRB to facilitate dynamic interaction between users and the
data resources on the Internet. Exciting times are here for corporations to have their
customers retrieve and update data on internal database servers, greatly streamlining
repetitive functions such as placing product orders and tracking the status of those
orders. Technology is changing rapidly, which is evidenced by the development of
newer technologies such as the WRB; an improvement upon the CGI handling of
dynamic requests on the Web. Even though CGI is being superseded within the Oracle
WebServer architecture by the WRB, it’s still a very popular interface because of its
simplicity. Several tools were developed to enhance CGI programming, including
some Perl libraries and the cgic library for the C language. These changes will provide
better and faster ways of processing information, making our lives easier and helping
companies who take advantage of the latest advances remain competitive.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 7
WebServer’s HTP Utilities
In order to provide an interface between native HTML and Oracle’s WebServer,
Oracle has developed a method for insulating the native HTML calls. Using
WebServer’s methodology, all HTML tags are generated on your behalf. When using
the Oracle WebServer, there is a standard library of HTML function calls that are used
to create the screen images. While similar in function to standard HTML tags, htp
(hypertext procedure) functions are called procedurally from within an Oracle stored
procedure. There is a one-to-one correspondence between the htp and htf (hypertext
function) libraries, but the htp calls are always used, except when functions need to be
embedded, or nested, within a single statement. It is not sufficient to call an htf
function because the HTML tag will not be passed to the Oracle PL/SQL Agent.
Therefore, it is always necessary to use the htp calls.
To understand the difference between an htf and an htp call, let’s consider an example
of an embedded htf call. Every htp procedure has a corresponding htf function call,
and the htp call should always be used unless there are htf calls that are nested within
a single htp call. For example:
will generate:
Nesting this htf call within the htp call results in:
As a general rule, you may nest as many htf calls as you like, as long as the outermost
call is an htp call.
Keep in mind that the htp calls will always generate HTML tags on your behalf. For
example, the following call
htp.headOpen;
htp.title('This is the header');
htp.headClose;
<HEAD>
<TITLE>This is the header</TITLE>
</HEAD>
The hypertext procedures and functions illustrated in this chapter can be grouped into
subcategories, based on their common functions. These groupings are outlined here as
a functional reference list. Later in the chapter, example code for many of these
procedures and functions will be presented in alphabetical order.
Print Procedures
Print procedures generate HTML tags related to printing information on a Web page.
This information can be static or dynamic in content, depending on the request being
processed.
• htp.print
• htp.prn
• htp.prints
• htp.ps
Structure Procedures
Structure procedures generate HTML tags that identify the structures within a Web
document. This generally translates to opening and closing sections of HTML code for
specific purposes. Each of the following procedures has a corresponding htf function
• htp.htmlOpen
• htp.htmlClose
• htp.headOpen
• htp.headClose
• htp.bodyOpen
• htp.bodyClose
Head Procedures
Head procedures generate HTML tags used for processing between the htp.headOpen
and htp.headClose procedures. These htp procedures are also available as htf
functions, which gives you greater flexibility in your application development.
• htp.title
• htp.isindex
• htp.linkRel
• htp.linkRev
• htp.meta
• htp.bodyOpen
• htp.bodyClose
Body Procedures
Body procedures generate HTML tags that are processed within the main section of
the text. Each of the following procedures has a corresponding htf function to assist in
the code-building process.
• htp.line
• htp.hr
• htp.nl
• htp.br
• htp.header
• htp.anchor
• htp.anchor2
• htp.mailto
• htp.img
• htp.img2
• htp.para
• htp.paragraph
• htp.address
• htp.Comment
• htp.preOpen
• htp.preClose
• htp.blockquoteOpen
• htp.blockquoteClose
• htp.base
• htp.area
• htp.mapOpen
• htp.mapClose
• htp.bgsound
• htp.div
• htp.listingOpen
• htp.listingClose
• htp.nobr
• htp.wbr
• htp.center
• htp.centerOpen
• htp.centerClose
• htp.big
• htp.small
• htp.sub
• htp.sup
• htp.basefont
• htp.fontOpen
• htp.fontClose
• htp.plaintext
• htp.s
• htp.strike
Frame Procedures
Frame procedures generate HTML tags that enable a Web page to be subdivided into
partitions, or frames. Each of these partitions may be defined with different structures
and characteristics to improve the presentation of that section of the document.
Note: Some Web browsers do not support the use of frames for displaying
HTML documents. Review the procedures in detail later in this chapter for
alternatives in handling this type of scenario.
• htp.framesetOpen
• htp.framesetClose
• htp.frame
• htp.noframesOpen
• htp.noframesClose
List Procedures
List procedures generate HTML tags that provide several options for listing
information on a Web page. List procedures have hypertext functions related to each
of the following procedures to assist in the code building process.
• htp.listHeader
• htp.listItem
• htp.ulistOpen
• htp.ulistClose
• htp.olistOpen
• htp.olistClose
• htp.dlistOpen
• htp.dlistClose
• htp.dlistDef
• htp.dlistTerm
• htp.menulistOpen
• htp.menulistClose
• htp.dirlistOpen
• htp.dirlistClose
Character format procedures generate HTML tags used to define the formatting
characteristics of text on a Web page. These procedures are also implemented as
hypertext functions (htf) to better address the functionality of your document.
• htp.cite
• htp.code
• htp.emphasis
• htp.em
• htp.keyboard
• htp.kbd
• htp.sample
• htp.strong
• htp.variable
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Physical Format procedures generate HTML tags that provide formatting options for text such
as boldface or italics. Each of these procedures also has a related hypertext function.
• htp.bold
• htp.italic
• htp.teletype
Form Procedures
Form procedures generate HTML tags that enable the use of forms within a Web page. These
forms can accept input in various ways to facilitate dynamic interaction between the user and
the Web application. Each htp form procedure has a corresponding hypertext function.
• htp.formOpen
• htp.formClose
• htp.formCheckbox
• htp.formHidden
• htp.formImage
• htp.formPassword
• htp.formRadio
• htp.formReset
• htp.formSubmit
• htp.formText
• htp.formSelectOpen
• htp.formSelectOption
• htp.formSelectClose
• htp.formTextarea
• htp.formTextarea2
• htp.formTextareaOpen
• htp.formTextareaOpen2
• htp.formTextareaClose
• htp.formTextareaClose2
Table Procedures
Table procedures generate HTML tags that enable tables to be used within a Web page. They
also provide several options, including inserting a row into a table. Each table procedure has a
corresponding hypertext function available to further your development capabilities.
• htp.tableOpen
• htp.tableClose
• htp.tableCaption
• htp.tableRowOpen
• htp.tableRowClose
• htp.tableHeader
• htp.tableData
HTP/HTF Parameters
The hypertext procedures and functions receive varchar2, integer, or date parameters. The
first position of the parameter name can be a c for character (varchar2), n for integer, or d for
date. The last parameter that may be used by many of the hypertext procedures and functions
is cattributes. This optional parameter allows HTML attributes to be sent to the PL/SQL
procedure.
htp.address
The htp.address procedure assigns an address to an HTML document. This enables the
document to be accessed by its address.
• cvalue—Names the address specified for the document (varchar2). Default NULL.
• cnowrap—Specifies that wrapping of lines is not allowed (varchar2). Default
NULL.
• cclear—Determines if you want to insert a new line (varchar2). Default NULL.
• cattributes—Settings for common HTML tags (varchar2). Default NULL.
htp.anchor
The htp.anchor hypertext procedure transfers users to another URL. The example used in
Listing 7.1 transfers the user to the s10 Web page when an image is clicked.
• curl—URL address of the gateway executable that will access the hypermedia text or
image you are linking to (varchar2).
• ctext—Hypermedia text or image used as the link (varchar2).
Listing 7.1 displays a PL/SQL code example using the htp.anchor procedure, and Listing 7.2
shows the HTML code generated by this procedure.
create or replace
procedure anchortst as
host_name_in varchar2(20);
begin
htp.htmlOpen;
htp.headOpen;
htp.title('anchortst');
htp.header(1,'Oracle WebServer');
htp.header(1,'Anchor Test','C');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 's10');
htp.FormHidden('host_name_in', host_name_in);
htp.nl;
htp.nl;
htp.anchor('/ows-bin/owa/s10?host_name_in=host_name_in',
htf.img('/ows-img/papaj.gif',
'left','alt_name','',
'HEIGHT=69, WIDTH=100 </IMG> <BR> <H1> Click on Bob for
host display/Update </H1>'));
htp.print('Host Name: ');
htp.FormText('host_name_in',10,50);
htp.nl;
htp.nl;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<TITLE>anchortst</TITLE>
<H1>Oracle WebServer</H1>
<H1 ALIGN="C">Anchor Test</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
<INPUT TYPE="hidden" NAME="host_name_in" VALUE="">
<BR>
<BR>
<A HREF="/ows-bin/owa/s10?host_name_in=host_name_in">
<IMG SRC="/ows-img/papaj.gif" ALIGN="left" ALT="alt_name"
HEIGHT=69, WIDTH=100 </IMG> <BR> <H1> Click on Bob for
host display/Update </H1>></A>
Host Name:
<INPUT TYPE="text" NAME="host_name_in" SIZE="10" MAXLENGTH="50">
<BR>
<BR>
</FORM>
</BODY>
</HTML>
htp.anchor2
The htp.anchor2 hypertext procedure defines the beginning and end destinations of a
hypertext link. The HREF attribute is defined through the parameter curl and tells us where to
target the link. The NAME attribute is defined through the cname parameter and enables the
tag to be the target of a hypertext link. The ctarget parameter allows a page to be framed,
which is created by setting width and height, and turning on scrolling.
• curl—URL address of the gateway executable that accesses the hypermedia text or
image you are linking to (varchar2).
• ctext—Hypermedia text or image used as the link (varchar2).
• cname—Name of this tag which allows it to be a target of a hypermedia link
(varchar2). Default NULL.
• ctarget—Defines this tag with a target name and allows it to be the target of a
hypertext link within a frame (varchar2). Default NULL.
• cattributes—Settings for common HTML tags (varchar2). Default NULL.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select
htp.area
The htp.area hypertext procedure defines how you want to shape an image map on the
client side of the request process. The region of the image map affected is defined by
the input coordinates.
htp.base
The htp.base hypertext procedure assigns a name to a document’s URL. This name
becomes the default window name for all links within the document.
htp.basefont
The htp.basefont hypertext procedure enables you to define the font size for the
document. This will be the base font size for the entire page.
Parameters: nsize(in)
• nsize—Defines the base font size for the Web page (integer).
htp.bgsound
The htp.bgsound hypertext procedure enables background sounds to play for the Web
page. You simply have to specify the audio file to be sourced.
htp.big
The htp.big hypertext procedure generates HTML tags that format text using a big
font. Displaying text in a larger font can improve the presentation of the Web page.
htp.blockquoteClose
The htp.blockquoteClose hypertext procedure ends quoted text. Text defined after the
tag <BLOCKQUOTE> is closed out by this procedure. There are no input or output
parameters related to this procedure.
htp.blockquoteOpen
NULL.
• cclear—Determines if you want to insert a newline (varchar2). Default
NULL.
• cattributes—Settings for common HTML tags (varchar2). Default NULL.
htp.bodyClose
This htp.bodyClose hypertext procedure indicates where the end of a screen body will
be placed. In general, there are no further screen mapping functions following a
bodyClose. This procedure has no related parameters.
htp.bodyOpen
The htp.bodyOpen hypertext procedure indicates the end of a header section and the
beginning of the screen body. You may add an image into the background of a
document to spruce things up a bit.
htp.bold
The htp.bold hypertext procedure makes printed text appear in a bold font. This is a
good feature for emphasizing important information on a page.
Note: See procedure htp.strong for examples of the PL/SQL and HTML
code related to this procedure.
htp.br
The htp.br hypertext procedure is used as an alias for the procedure htp.nl, which
submits a new line into the body of an HTML document.
htp.center
The htp.center hypertext procedure centers text on a Web page. This procedure is
helpful for arranging the text on the document and improving its readability.
Parameters: ctext(in)
htp.centerClose
htp.centerOpen
htp.cite
The htp.cite hypertext procedure formats cited text on a Web page. This is a good way
to emphasize information displayed on a document.
htp.code
The htp.code hypertext procedure displays text in code format (usually displayed as
monotype). This is useful for outputting text that would be more understandable when
displayed as code.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.comment
This htp.comment hypertext procedure allows you as a developer to place comments within
the source code of a Web page. The benefit is that the comments are not visible to the user
displaying the document.
Parameters: ctext(in)
htp.dirlistClose
The htp.dirlistClose hypertext procedure generates an HTML tag that ends a directory list. A
directory list is a specially formatted list of items. There are no parameters related to this
procedure.
Note: See procedure htp.dirlistOpen for examples of the PL/SQL and HTML code
related to this procedure.
htp.dirlistOpen
The htp.dirlistOpen hypertext procedure creates an HTML tag that starts a directory list. The
directory list is a specially formatted list of items. Notice that in the Web page shown in Figure
7.2, the items are displayed as bulleted text. This procedure has no parameters for input or
output.
Note: The htp.listItem procedure call must follow the call to procedure htp.
dirlistOpen.
Listing 7.3 displays a PL/SQL code example using the htp.dirlistOpen procedure, and Listing
7.4 shows the HTML code generated by this procedure.
create or replace
procedure dirlist as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.dirlist Example');
htp.headClose;
htp.bodyOpen;
htp.dirlistOpen;
htp.listHeader('Installation Specifications');
htp.listItem('Item 1: Oracle WebServer 2 was installed with
Oracle 7.3.2.1');
htp.listItem('Item 2: The operating system is Solaris 2.5 on
an Ultra 1');
htp.listItem('Item 3');
htp.listItem('Item 4');
htp.dirlistClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.dirlist Example</H1>
</HEAD>
<BODY>
<DIR>
<LH>Installation Specifications</LH>
<LI>Item 1: Oracle WebServer 2 was installed with Oracle 7.3.2.1
<LI>Item 2: The operating system is Solaris 2.5 on an Ultra 1
<LI>Item 3
<LI>Item 4
</DIR>
</BODY>
</HTML>
htp.div
The htp.div hypertext procedure partitions a document. Partitioning enables you to place
whatever text or images you want anywhere on the Web page.
Listing 7.5 displays a PL/SQL code example using the htp.div procedure, and Listing 7.6
shows the HTML code generated by this procedure.
create or replace
procedure divprc as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.div Example');
htp.headClose;
htp.bodyOpen;
htp.div('right');
htp.print('Display Text on Right Partition');
htp.nl;
htp.print('This is the Oracle DB Recovery Flamingo');
htp.nl;
htp.div('left');
htp.print('Display Image on Left Partition');
htp.nl;
htp.img('/ows-img/flamingo.gif');
htp.nl;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.div Example</H1>
</HEAD>
<BODY>
<DIV ALIGN="right">
htp.dlistClose
The htp.dlistClose hypertext procedure ends a list of definitions. These definitions are listed in
an indented format. There are no parameters for this procedure.
Note: See procedure htp.dlistDef for examples of the PL/SQL and HTML code
related to this procedure.
htp.dlistDef
The htp.dlistDef procedure creates an HTML tag to build a list of definitions. Terms can be
inserted within this list using the htp.dlistTerm procedure. Notice in the Web page displayed
in Figure 7.4 that the terms appear in an indented format within the definition list.
Note: To insert the terms within the definition list, the htp.dlistTerm procedure call
must follow the htp.dlistDef procedure call.
Listing 7.7 displays a PL/SQL code example using the htp.dlistDef procedure, and Listing 7.8
create or replace
procedure dlistprc as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.dlistDef Example');
htp.headClose;
htp.bodyOpen;
htp.dlistOpen;
htp.dlistDef('Definition List 1');
htp.dlistTerm('Definition Term 1');
htp.dlistTerm('Definition Term 2');
htp.dlistTerm('Definition Term 3');
htp.dlistTerm('Definition Term 4');
htp.dlistTerm('Definition Term 5');
htp.dlistClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.dlistDef Example</H1>
</HEAD>
<BODY>
<DL>
<DD>Definition List 1
<DT>Definition Term 1
<DT>Definition Term 2
<DT>Definition Term 3
<DT>Definition Term 4
<DT>Definition Term 5
</DL>
</BODY>
</HTML>
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.dlistOpen
The htp.dlistOpen hypertext procedure creates an HTML tag to open an indented list
of definitions in a definition list.
Note: See procedure htp.dlistDef for examples of the PL/SQL and HTML
code related to this procedure.
htp.dlistTerm
The htp.dlistTerm hypertext procedure generates an HTML tag to list terms within a
definition list. The terms are listed in an indented format, following the definition list
name. The htp.dlistTerm procedure call must immediately follow the call to the htp.
dlistDef procedure.
Note: See procedure htp.dlistDef for examples of the PL/SQL and HTML
code related to this procedure.
htp.em
The htp.em hypertext procedure is the alias for the procedure htp.emphasis. This
alias will highlight the specified text.
htp.emphasis
The htp.emphasis hypertext procedure highlights text specified as input. The type of
highlighting employed may vary, but in most instances, the text appears italicized.
htp.fontClose
The htp.fontClose hypertext procedure ends a section of text using special, defined-
font settings. There are no parameters necessary for this procedure.
htp.fontOpen
The htp.fontOpen hypertext procedure begins a section of text using special, defined-
font settings. This is helpful for making portions of the text stand out.
htp.formCheckbox
• cname—Defines the internal reference name for the contents of the field
(varchar2). The name for each checkbox button should be different because
you can make multiple selections.
• cvalue—Indicates the value for the checkbox button (varchar2). Default
ON. Each checkbox button should have the same value indicating that it was
selected. The name of the button should provide distinguishing information for
that button.
• cchecked—Defines a button as checked (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
Listing 7.9 displays a PL/SQL code example using the htp.formCheckbox procedure,
and Listing 7.10 shows the HTML code generated by this procedure.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
create or replace
procedure formcheckbox (tab_name in varchar2) is
cursor cols is
select
column_name
from
dba_tab_columns
where
table_name = upper(tab_name);
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.htitle('Query the '||tab_name||' table by checking columns
below.');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path||'do_query');
htp.formHidden('tab_name', tab_name);
htp.formHidden('COLS', 'dummy');
<HTML>
<HEAD>
<TITLE>Query the dba_tables table by checking columns below.</TITLE>
<H1>Query the dba_tables table by checking columns below.</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/do_query" METHOD="POST">
<INPUT TYPE="hidden" NAME="tab_name" VALUE="dba_tables">
<INPUT TYPE="hidden" NAME="COLS" VALUE="dummy">
<INPUT TYPE="checkbox" NAME="COLS" VALUE="OWNER">
OWNER
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="TABLE_NAME">
TABLE_NAME
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="TABLESPACE_NAME">
TABLESPACE_NAME
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="CLUSTER_NAME">
CLUSTER_NAME
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="PCT_FREE">
PCT_FREE
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="PCT_USED">
PCT_USED
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="INI_TRANS">
INI_TRANS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="MAX_TRANS">
MAX_TRANS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="INITIAL_EXTENT">
INITIAL_EXTENT
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="NEXT_EXTENT">
NEXT_EXTENT
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="MIN_EXTENTS">
MIN_EXTENTS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="MAX_EXTENTS">
MAX_EXTENTS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="PCT_INCREASE">
PCT_INCREASE
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="FREELISTS">
FREELISTS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="FREELIST_GROUPS">
FREELIST_GROUPS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="BACKED_UP">
BACKED_UP
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="NUM_ROWS">
NUM_ROWS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="BLOCKS">
BLOCKS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="EMPTY_BLOCKS">
EMPTY_BLOCKS
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="AVG_SPACE">
AVG_SPACE
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="CHAIN_CNT">
CHAIN_CNT
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="AVG_ROW_LEN">
AVG_ROW_LEN
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="DEGREE">
DEGREE
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="INSTANCES">
INSTANCES
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="CACHE">
CACHE
<BR>
<INPUT TYPE="checkbox" NAME="COLS" VALUE="TABLE_LOCK">
TABLE_LOCK
<BR>
<INPUT TYPE="submit" VALUE="Execute Query">
</FORM>
</BODY>
</HTML>
htp.formClose
The htp.formClose hypertext procedure closes an HTML form. Forms are opened by the htp.
formOpen procedure. There are no parameters for this procedure.
Note: See procedure htp.formSelectOpen for examples of the PL/SQL and HTML code
related to this procedure.
htp.formHidden
The htp.formHidden hypertext procedure sends a field value with a form. However, the user will
not see the value as part of the transmission.
• cname—Defines the internal reference name for the contents of the field (varchar2).
• cvalue—Assigns the value of the field (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
Note: See procedure htp.formCheckbox for examples of the PL/SQL and HTML code
related to this procedure.
htp.formImage
The htp.formImage hypertext procedure posts an image that can be clicked on to submit a form.
Creating an image map is accomplished by using a combination of the formImage and formOpen
hypertext procedures. As you can see in Listing 7.11, the formImage procedure parameters include
the internal name of the image (BobPic), and the actual image file (papaj.gif, which, in this case,
happens to be me). Now, you also need the formOpen procedure to tell the Web Listener where you
are transferring to based on where you clicked on the image. The hotspots on the image are defined
by X and Y coordinates. This cumbersome task of defining hotspots on image maps was discussed in
the CGI chapter. When you click on a specific X,Y coordinate on an image, three parameters are
passed to the URL identified in the formOpen procedure. The URL in Listing 7.11 is the procedure
called ‘s00’, which must be set up to receive the three parameters, including the internal image
name, the X coordinate, and the Y coordinate. So, if you click on Bob’s nose, you go to one URL,
and if you click on Bob’s ear, you go to another location. For another perspective on the relationship
between the formOpen and formImage procedures, see the htp.formOpen definition.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Listing 7.11 displays a PL/SQL code example using the htp.formImage procedure, and Listing 7.12
shows the HTML code generated by this procedure.
create or replace
procedure formimage as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver formImage');
htp.header(1,'Oracle WebServer htp.formImage Examples');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 's00');
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<TITLE>Oracle Webserver formImage</TITLE>
<H1>Oracle WebServer htp.formImage Examples</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/s00" METHOD="POST">
Click on the Image to submit Form
<INPUT TYPE="image" NAME="BobPic" SRC="/ows-img/papaj.gif">
<BR>
</FORM>
</BODY>
</HTML>
htp.formOpen
The htp.formOpen hypertext procedure specifies the name of the procedure that will be invoked when a
form is submitted. Generally, a form is submitted using htp.formSubmit or htp.formImage. The
formOpen is always used in combination with either formSubmit or formImage.
• curl—This is the URL identifying the executable script (e.g., CGI) that will generate the form
(varchar2).
• cmethod—This is the method used to transfer data to and from the form (varchar2). Default
POST. The other option is GET.
• ctarget—This parameter should be left blank (varchar2).
• cenctype—This is the encryption type for the data being transferred (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
For example, this pair will create a push button, which, when clicked, will create the Web page defined in
the stored procedure called destination_page_name :
htp.formOpen(owa_util_.get_owa_service_path||'destination_page_name');
htp.formSubmit(NULL, 'Press here to transfer to destination Web page');
Note: Normally a stored procedure name is used with htp.formSubmit, but here NULL is used,
so the stored procedure specified by htp.formOpen is used.
In this example, a form image will be created which, when clicked, will create the Web page that is
defined in the stored procedure called destination_page_name :
htp.formOpen(owa_util_.get_owa_service_path||'destination_page_name');
htp.formImage('internal_image_name','actual_image_file_name');
internal_image_name varchar2;
internal_image_name.x int;
internal_image_name.y int;
where x is the X pixel coordinate and y is the Y pixel coordinate. These coordinates are used by the
receiving page to interrogate the pixel coordinates and transfer to other functions. Therefore, in this case,
destination_procedure_name would need to be defined with these three input parameters. Here is the
prototype:
destination_procedure_name(internal_image_in in varchar2,
internal_image_in.x in int, internal_image_in.y in int);
htp.formPassword
• cname—Defines the internal reference name for the contents of the field (varchar2).
• csize—Defines the displayed number of characters (varchar2).
• cmaxlength—Defines the maximum number of characters that the field can contain (varchar2).
Default NULL.
• cvalue—Defines the value associated with the password (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
Note: A text field with csize=5 and cmaxlength=10 will only display 5 characters, but it will be
able to accept 10 characters. In this case, you may enter 10 characters, and use the arrow keys to
display the entire text string.
Listing 7.13 displays a PL/SQL code example using the htp.form Password procedure, and Listing 7.14
shows the HTML code generated by this procedure.
create or replace
procedure formpassword as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver formPassword');
htp.header(1,'Oracle WebServer htp.formPassword Examples');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 'formpassword');
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<TITLE>Oracle Webserver formPassword</TITLE>
<H1>Oracle WebServer htp.formPassword Examples</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/formpassword" METHOD="POST">
ENTER Userid:
<INPUT TYPE="text" NAME="Userid" SIZE="10" MAXLENGTH="50">
<BR>
ENTER Password:
<INPUT TYPE="password" NAME="Password" SIZE="10" MAXLENGTH="50">
<BR>
</FORM>
</BODY>
</HTML>
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.formRadio
The htp.formRadio hypertext procedure inserts a radio button into an HTML form.
• cname—Defines the internal reference name for the contents of the field (varchar2).
Each radio button should have the same name because you can only select one.
• cvalue—Assigns the value associated with this button (varchar2). For example, one radio
button might have the value “Visa” and another “Amex”.
• cchecked—Indicates that the button default is “checked” (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
Listing 7.15 displays a PL/SQL code example using the htp.formRadio procedure, and Listing
7.16 shows the HTML code generated by this procedure.
create or replace
procedure formradio is
cursor cols is
select
nationality
from
nations
order by nationality
;
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.htitle('Choose a nationality.');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path||'formradio');
htp.formHidden('COLS', 'dummy');
for crec in cols loop
htp.formRadio('COLS',crec.nationality);
htp.print(crec.nationality);
htp.nl;
end loop;
<HTML>
<HEAD>
<TITLE>Choose a nationality.</TITLE>
<H1>Choose a nationality.</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/formradio" METHOD="POST">
<INPUT TYPE="hidden" NAME="COLS" VALUE="dummy">
<INPUT TYPE="radio" NAME="COLS" VALUE="Bosnia">
Bosnia
<BR>
<INPUT TYPE="radio" NAME="COLS" VALUE="Finnish">
Finnish
<BR>
<INPUT TYPE="radio" NAME="COLS" VALUE="Slobovia">
Slobovia
<BR>
<INPUT TYPE="radio" NAME="COLS" VALUE="USA">
USA
<BR>
<INPUT TYPE="submit" VALUE="Execute Query">
</FORM>
</BODY>
</HTML>
htp.formReset
The htp.formReset hypertext procedure inserts a Reset button into an HTML form, which can be
used to reset all the input data fields to their original values.
• cvalue—Defines the value associated with the button (varchar2). Defaults to Reset.
• cattributes—Settings to define the HTML tag attributes (varchar2). Default NULL.
Listing 7.17 displays a PL/SQL code example using the htp.formReset procedure, and Listing
7.18 shows the HTML code generated by this procedure.
create or replace
procedure formreset as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver formReset');
htp.header(1,'Oracle WebServer htp.formReset Examples');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 'formreset');
htp.formReset;
htp.nl;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<TITLE>Oracle Webserver formReset</TITLE>
htp.formSelectClose
The htp.formSelectClose hypertext procedure ends a list of selections. This HTML section is
opened by the htp.formSelectOpen procedure. There are no parameters for this procedure.
Note: See procedure htp.formSelectOpen for examples of the PL/SQL and HTML code
related to this procedure.
htp.formSelectOpen
Listing 7.19 displays a PL/SQL code example using the htp.formSelectOpen procedure, and
Listing 7.20 shows the HTML code generated by this procedure.
create or replace
procedure formselectopen as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver formSelectOpen');
htp.formOpen(owa_util.get_owa_service_path || 'test');
htp.formSelectOpen('input_var_name:','Choose the Server Site:');
htp.nl;
htp.nl;
htp.formSelectOption('Buffalo');
htp.nl;
htp.formSelectOption('Rochester');
htp.nl;
htp.formSelectOption('Syracuse');
htp.nl;
htp.formSelectClose;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
<HTML>
<HEAD>
<TITLE>Oracle Webserver formSelectOpen</TITLE>
<H1>Oracle WebServer htp.formSelectOpen Examples</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/test" METHOD="POST">
Choose the Server Site:<SELECT NAME="input_var_name:">
<BR>
<BR>
<OPTION>Buffalo
<BR>
<OPTION>Rochester
<BR>
<OPTION>Syracuse
<BR>
</SELECT>
</FORM>
</BODY>
</HTML>
Note: Rather than hard-coding the pop-up values in the form, you can retrieve the
values from your Oracle database and dynamically create a Web page with the
database values. To see how to dynamically generate pop-up lists, see Chapter 10.
htp.formSelectOption
The htp.formSelectOption hypertext procedure represents one selection from a list. This
list is displayed within the context of an HTML form.
htp.formSubmit
• cname—Defines the internal reference name for the form (varchar2). Default
NULL.
• cvalue—Identifies the button as one being used for submitting forms (varchar2).
Default Submit.
• cattributes—Settings for the attributes of HTML tags (varchar2). Default
NULL.
Note: See procedure htp.formRadio for examples of the PL/SQL and HTML
code related to this procedure.
htp.formText
The htp.formText function creates an input field for textual data entry and updates.
• cname—Defines the internal reference name for the contents of the field
(varchar2).
• csize—Assigns the displayed number of characters in the field (varchar2).
Default NULL.
• cmaxlength—Defines the maximum number of characters that the field can
contain (varchar2). Default NULL.
• cvalue—Indicates the default text within the field (varchar2). Default NULL.
• cattributes—Settings for the attributes of HTML tags (varchar2). Default
NULL.
Note: A text field with csize=5 and cmaxlength=10 will only display 5
characters, but will be able to accept 10 characters. In this case, you may enter 10
characters, and use the arrow keys to display the entire text string.
Listing 7.21 displays a PL/SQL code example using the htp.formText procedure, and
Listing 7.22 shows the HTML code generated by this procedure.
create or replace
procedure formtext as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver formText');
htp.header(1,'Oracle WebServer htp.formText Examples');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 'formtext');
htp.print('Size 1: ');
htp.formText('U',10,50);
htp.nl;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<TITLE>Oracle Webserver formText</TITLE>
<H1>Oracle WebServer htp.formText Examples</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/formtext" METHOD="POST">
Size 1:
<INPUT TYPE="text" NAME="U" SIZE="10" MAXLENGTH="50">
<BR>
Size 10:
<INPUT TYPE="text" NAME="V" SIZE="10" MAXLENGTH="50">
<BR>
Size 20:
<INPUT TYPE="text" NAME="W" SIZE="20" MAXLENGTH="50">
<BR>
Size 30:
<INPUT TYPE="text" NAME="X" SIZE="30" MAXLENGTH="50">
<BR>
Size 40:
<INPUT TYPE="text" NAME="Y" SIZE="40" MAXLENGTH="50"
VALUE="This is a default value">
<BR>
</FORM>
</BODY>
</HTML>
htp.formTextarea
The htp.formTextarea hypertext procedure creates a text area that does not have any
predefined text. This procedure enables a user to enter text into the text field.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.formTextarea2
The htp.formTextarea2 hypertext procedure creates a text area that does not have any
predefined text and allows text to be entered by a user into the text field. However, this
procedure is different from htp.formTextarea in that it allows for a wrap style for the
text.
htp.formTextareaClose
The htp.formTextareaClose hypertext procedure ends a text area field defined with
procedure htp.formTextarea. There are no parameters necessary for this procedure.
htp.formTextareaClose2
The htp.formTextareaClose2 hypertext procedure ends a text area field defined with
htp.formTextareaOpen
formTextareaOpen2
The formTextareaOpen2 hypertext procedure begins a text area with predefined text.
The predefined text will always be displayed in the text field. This procedure allows
for the specification of a wrap style for the text.
htp.frame
The htp.frame hypertext procedure generates an HTML tag that defines a frame. A
frame is a way of separating data or functions into different windows within a Web
page, thus enabling distinct processing to occur within partitioned sections of the
document.
htp.framesetClose
htp.framesetOpen
The htp.framesetOpen hypertext procedure begins a set of frames within a Web page.
There are no required parameters associated with this procedure.
htp.headClose
The htp.headClose hypertext procedure specifies the end of the head in the HTML
document. There are no parameters associated with this procedure. The HTML head is
opened by hypertext procedure htp.headOpen.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.header
The htp.header hypertext procedure defines your HTML document headings. You’ll notice that different levels defined
for headers represent different font sizes.
Listing 7.23 displays a PL/SQL code example using the htp.header procedure, and Listing 7.24 shows the HTML code
generated by this procedure.
create or replace
procedure header as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.header Example');
htp.header(2,'Oracle WebServer htp.header Example');
htp.header(3,'Oracle WebServer htp.header Example');
htp.header(4,'Oracle WebServer htp.header Example');
htp.header(5,'Oracle WebServer htp.header Example');
htp.header(6,'Oracle WebServer htp.header Example');
htp.headClose;
htp.bodyOpen;
htp.nl;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.header Example</H1>
<H2>Oracle WebServer htp.header Example</H2>
<H3>Oracle WebServer htp.header Example</H3>
<H4>Oracle WebServer htp.header Example</H4>
<H5>Oracle WebServer htp.header Example</H5>
<H6>Oracle WebServer htp.header Example</H6>
</HEAD>
<BODY>
<BR>
</BODY>
</HTML>
htp.headOpen
The htp.headOpen hypertext procedure specifies the beginning of an HTML document head. There are no input or
output parameters for this procedure.
htp.hr
The htp.hr hypertext procedure is an alias for procedure htp.line. The htp.line procedure creates a line within the HTML
document.
htp.htmlClose
The htp.htmlClose hypertext procedure specifies the end of your HTML code. This procedure has no parameters
associated with it. The HTML document is opened with procedure htp.htmlOpen.
htp.htmlOpen
The htp.htmlOpen hypertext procedure specifies the beginning of your HTML code. There are no input or output
parameters related to this procedure.
htp.img
The htp.img hypertext procedure displays images on a Web page. In addition, coding can be added to make the image
function as a push button or to map different parts of the image to different responses.
Listing 7.25 displays a PL/SQL code example using the htp.img procedure, and Listing 7.26 shows the HTML code
generated by this procedure.
create or replace
procedure img as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('img');
htp.header(1,'Oracle WebServer');
htp.header(1,'Image Example');
htp.headClose;
htp.bodyOpen;
htp.nl;
htp.nl;
htp.img('/ows-img/iconmngr.gif');
htp.nl;
htp.anchor('/ows-bin/owa/s10',htf.img('/ows-img/burleson.gif','','','',
'HEIGHT=100, WIDTH=120 <BR>
<H1> Click on Don to go to procedure s10 </H1>'));
htp.anchor('/ows-bin/owa/s20',htf.img('/ows-img/papaj.gif','','',
'ISMAP','HEIGHT=100, WIDTH=120 <BR> <H1> Bob is an image map, and
procedure s20 will receive the map coordinates </H1>'));
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Note that the first static image call (htp.img) is very straightforward, but it is not clear where the image is being loaded
from. In this case, the call htp.img(‘/ows-img/iconmngr.gif’), tells the WebServer to load iconmngr.gif from the
directory specified in the WebServer Listener Administration—Directory Mappings—with the virtual directory ‘/ows-
img’ (see Figure 7.13).
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/ch07/208-213.html (5 of 7)4/03/2005 6:15:48
Oracle Databases on the Web:WebServer's HTP Utilities
Figure 7.13 The Directory Mappings page within WebServer Listener Administration.
<HTML>
<HEAD>
<TITLE>img</TITLE>
<H1>Oracle WebServer</H1>
<H1>Image Example</H1>
</HEAD>
<BODY>
<BR>
<BR>
<IMG SRC="/ows-img/iconmngr.gif">
<BR>
This is a static Image
<BR>
<BR>
<BR>
<A HREF="/ows-bin/owa/s10"><IMG SRC="/ows-img/burleson.gif"
HEIGHT=100, WIDTH=120 <BR> <H1> Click on Don to go to procedure s10
</H1>></A>
<A HREF="/ows-bin/owa/s20"><IMG SRC="/ows-img/papaj.gif"
ISMAP HEIGHT=100, WIDTH=120 <BR> <H1> Bob is an image map, and
procedure s20 will receive the map coordinates </H1>></A>
</BODY>
</HTML>
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.img2
The htp.img2 hypertext procedure loads an image into a Web page. You will notice that there can be
alternate hypertext displayed with the image. This procedure can source an image from the client site. That
is, the map file for the image map is stored within the HTML document, which allows for all processing to
occur locally. The map file contains the link and region instructions for the image map.
Note: Your Web browser needs to be client-side compatible to use the htp.img2 procedure. The
current versions of Netscape and Internet Explorer are compatible.
htp.isindex
The htp.isindex hypertext procedure generates an HTML tag that sends text as a prompt to a URL site.
Usually, a program or Web page will receive this information.
htp.italic
The htp.italic hypertext procedure places italicized text on a Web page. This type of highlighting is an
effective feature for clarifying the information presented. You will notice in this example two ways to
italicize text. One is by using the htp.italic procedure as a standalone process. The second is to embed this
procedure as a hypertext function within the htp.print procedure.
Listing 7.27 displays a PL/SQL code example using the htp.italic procedure, and Listing 7.28 shows the
HTML code generated by this procedure.
create or replace
procedure italic as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.italic Example');
htp.headClose;
htp.bodyOpen;
htp.nl;
htp.italic('This is italicized TEXT');
htp.nl;
htp.print(htf.italic('Printed Italics'));
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.italic Example</H1>
</HEAD>
<BODY>
<BR>
<I>This is italicized TEXT</I>
<BR>
<I>Printed Italics</I>
</BODY>
</HTML>
htp.kbd
The htp.kbd hypertext procedure is an alias for the htp.keyboard procedure. The procedure will display
text in monospace, as it would be entered by a user.
Note: See procedure htp.keyboard for examples of PL/SQL and HTML code related to this
procedure.
htp.keyboard
The htp.keyboard hypertext procedure displays text as if it were entered by a user. This means that all the
characters are displayed in monospace typeface.
Listing 7.29 displays a PL/SQL code example using the htp.keyboard procedure, and Listing 7.30 shows
the HTML code generated by this procedure.
create or replace
procedure keyboard as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.keyboard Example');
htp.headClose;
htp.bodyOpen;
htp.nl;
htp.keyboard('A media failure occurred at 12 midnight.');
htp.nl;
htp.keyboard('After replacing the disk and restoring the OS files,');
htp.nl;
htp.kbd('we did a point-in-time recovery.');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.keyboard Example</H1>
</HEAD>
<BODY>
<BR>
<KBD>A media failure occurred at 12 midnight.</KBD>
<BR>
<KBD>After replacing the disk and restoring the OS files,</KBD>
<BR>
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
htp.line
The htp.line hypertext procedure generates an HTML tag that creates lines within a Web
page. This feature can be used to better separate information on a document.
Listing 7.31 displays a PL/SQL code example using the htp.line procedure, and Listing 7.32
shows the HTML code generated by this procedure.
create or replace
procedure line as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.line Example');
htp.headClose;
htp.bodyOpen;
htp.nl;
htp.line;
htp.line;
htp.nl;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.line Example</H1>
</HEAD>
<BODY>
<BR>
<HR>
This text appears between the lines
<HR>
<BR>
</BODY>
</HTML>
htp.linkRel
The htp.linkRel hypertext procedure generates an HTML tag that describes the relationship
of a hyperlink between an htp.anchor procedure and the target URL. Essentially, this is the
next link within this document. The htp.anchor procedure actually creates the hyperlink and
must use the HREF attribute for the htp.linkRel procedure to function correctly.
• crel—Defines the relationship between htp.anchor and the target URL (varchar2).
Default NULL.
• curl—Identifies the target URL (varchar2).
• ctitle—Defines the title given to the relationship (varchar2). Default NULL.
htp.linkRev
The htp.linkRev hypertext procedure is the reverse of the procedure htp.linkRel and
describes the relationship of the hyperlink from the target to the htp.anchor point. This
basically is the previous link within this document. The hyperlink is actually created by the
htp.anchor procedure, not htp.linkRev.
• crev—Defines the relationship between the target URL and the htp.anchor point
(varchar2). Default NULL.
• curl—Identifies the target URL (varchar2).
• ctitle—Defines the title given to the relationship (varchar2). Default NULL.
htp.listHeader
The htp.listHeader hypertext procedure generates an HTML tag to create a heading for an
item list. The procedure call to htp.listHeader precedes the call to procedure htp.listItem.
Note: See procedure htp.dirlistOpen for examples of PL/SQL and HTML code
related to this procedure.
htp.listingClose
The htp.listingClose hypertext procedure creates an HTML tag that ends a listing of fixed-
width text. There are no parameters associated with this procedure.
Note: See procedure htp.listingOpen for examples of PL/SQL and HTML code
related to this procedure.
htp.listingOpen
The htp.listingOpen hypertext procedure creates a listing with fixed-width text. It is used in
conjunction with the htp.listItem procedure to produce the listing. There are no parameters
for this procedure.
Listing 7.33 displays a PL/SQL code example using the htp.listingOpen procedure, and
Listing 7.34 shows the HTML code generated by this procedure.
create or replace
procedure listing as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.listingOpen Example');
htp.headClose;
htp.bodyOpen;
htp.nl;
htp.listingOpen;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.listingOpen Example</H1>
</HEAD>
<BODY>
<BR>
<LISTING>
<LI>Reorg the data by exporting the tables in compressed mode,
<LI>dropping the tables, then importing the data and structures
<LI>into one extent.
</LISTING>
</BODY>
</HTML>
htp.listItem
The htp.listItem hypertext procedure produces an HTML tag that will enable the formatting
of an item. These items will comprise a listing created to your specifications.
Note: See procedure htp.dirlistOpen for examples of the PL/SQL and HTML code
related to this procedure.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select
htp.mailto
The htp.mailto hypertext procedure concatenates the mailto identifier to the front of the address
of the anchor. This is useful for sending mail messages to an email address. When the message is
received, the recipient can click on the hypertext to open a dialog box with the subject and body
of the message and then respond as necessary. Most, but not all, Web browsers are compatible
with the mailto protocol.
For example, the HREF attribute generated from this procedure would be formatted like:
HREF="mailto:caddress"
htp.mapClose
The htp.mapClose hypertext procedure generates an HTML tag to close the specification for a
client-side image map. The definition for this image map is opened by the procedure htp.
mapOpen. There are no input or output parameters related to this procedure.
htp.mapOpen
The htp.mapOpen hypertext procedure begins the definition of an image map sourced from the
client site. Client-side image maps store map files within an HTML document, so all processing
of the HTML document is local. These files contain the link and region instructions for the
document.
htp.menulistClose
The htp.menulistClose hypertext procedure closes a menu list. There are no parameters
associated with this procedure. A menu list is opened by the hypertext procedure htp.
menulistOpen.
Note: See procedure htp.menulistOpen for examples of the PL/SQL and HTML code
related to this procedure.
htp.menulistOpen
The htp.menulistOpen hypertext procedure begins a menu list on a Web page, which is
displayed as a compact bullet list. There are no input or output parameters related to this
procedure. A menu list is closed by using the hypertext procedure htp.menulistClose. There are
no parameters associated with this procedure.
Listing 7.35 displays a PL/SQL code example using the htp.menulistOpen procedure, and
Listing 7.36 shows the HTML code generated by this procedure.
create or replace
procedure menulist as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.menulist Example');
htp.headClose;
htp.bodyOpen;
htp.menulistOpen;
htp.listHeader('Server Information');
htp.listItem('Item 1: Hostname: Spartan');
htp.listItem('Item 2: OS: Solaris 2.5');
htp.listItem('Item 3: #CPUs: 4');
htp.listItem('Item 4: RAM: 256mb');
htp.menulistClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.menulist Example</H1>
</HEAD>
<BODY>
<MENU>
<LH>Server Information</LH>
<LI>Item 1: Hostname: Spartan
<LI>Item 2: OS: Solaris 2.5
<LI>Item 3: #CPUs: 4
<LI>Item 4: RAM: 256mb
</MENU>
</BODY>
</HTML>
htp.meta
The htp.meta hypertext procedure sends metadata to the Web browser about information being
transferred to it. This information helps to identify what is being returned to assist in determining
the disposition of the feed.
In this example, the current URL is refreshed (or reloaded) automatically every 60 seconds:
htp.nl
The htp.nl hypertext procedure inserts a new line into the HTML document. This helps space out
the items on a Web page to improve the clarity of the presentation. There are no parameters
associated with this procedure.
htp.nobr
The htp.nobr hypertext procedure marks a section of text within a Web document as not
containing line breaks. This will be useful for displaying text more compactly.
Parameters: ctext(in)
htp.noframesClose
htp.noframesOpen
The htp.noframesOpen hypertext procedure generates an HTML tag that opens a set of frame-
like content within a Web browser that cannot display frames. There are no parameters related to
this procedure.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select
htp.olistClose
The htp.olistClose hypertext procedure creates an HTML tag to end an ordered list of
items. Using ordered lists can be a good presentation aid for a Web page by allowing
numbered identification of items. There are no parameters associated with this
procedure.
Note: See procedure htp.olistOpen for examples of the PL/SQL and HTML
code related to this procedure.
htp.olistOpen
The htp.olistOpen hypertext procedure creates an HTML tag that opens a list of items
that are ordered. Notice in Listing 7.37 that numbers are automatically generated for
each item in the listing.
• cclear—Inserts a new line into the Web page (varchar2). Default NULL.
• cwrap—Specifies a wrap style for the document (varchar2). Default NULL.
• cattributes—Settings for attributes of HTML tags (varchar2). Default NULL.
Listing 7.37 displays a PL/SQL code example using the htp.olistOpen procedure, and
Listing 7.38 shows the HTML code generated by this procedure.
create or replace
procedure olistprc as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.olistOpen Example');
htp.headClose;
htp.bodyOpen;
htp.olistOpen;
htp.listItem('Olist Item: Export the table');
htp.listItem('Olist Item: Drop the table');
htp.listItem('Olist Item: Create the table/indexes');
htp.listItem('Olist Item: Import the data');
htp.olistClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.olistOpen Example</H1>
</HEAD>
<BODY>
<OL>
<LI>Olist Item: Export the table
<LI>Olist Item: Drop the table
<LI>Olist Item: Create the table/indexes
<LI>Olist Item: Import the data
</OL>
</BODY>
</HTML>
htp.para
The htp.para hypertext procedure specifies that the text preceding it. There are no
parameters associated with this procedure.
htp.paragraph
The htp.paragraph hypertext procedure defines the text preceding its call as being
formatted as a paragraph. This procedure is the same as the htp.para procedure except
you are able to define specific formatting characteristics.
htp.plaintext
The htp.plaintext hypertext procedure generates a pair of HTML tags that mark the text
as being fixed-width. Plain text is one of the most common text formats used within
documents.
htp.preClose
htp.preOpen
The htp.preOpen hypertext procedure sets preformatted text on a Web page. Web
browsers normally format HTML text and ignore any miscellaneous spaces, tabs, or line
returns. Preformatted text would be displayed exactly as it is typed, including the spaces,
tabs, and line returns. In the example in Listing 7.39, we see the htp.header information
being centered on the Web page.
Listing 7.39 displays a PL/SQL code example using the htp.preOpen procedure, and
Listing 7.40 shows the HTML code generated by this procedure.
create or replace
procedure s00 as
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.title('s00');
htp.preOpen;
htp.header(1,' Oracle Information Database');
htp.header(1,' Main Menu','C');
htp.headClose;
htp.preClose;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<TITLE>s00</TITLE>
<PRE>
<H1> Oracle Information Database</H1>
<H1 ALIGN="C"> Main Menu</H1>
</HEAD>
</PRE>
</FORM>
</BODY>
</HTML>
htp.p
The htp.p hypertext procedure is the alias for the procedure htp.print. The same
parameters apply in both cases.
htp.print
The htp.print hypertext procedure displays text on an HTML document. The input data
can be typed as either varchar2, date, or number.
Parameters: ctext(in)
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.prints
The htp.prints hypertext procedure displays a line of text within a Web page after replacing all
occurrences of certain special characters within the text. Without replacing these special characters,
they can be confused with HTML control characters and disrupt the whole process. The special
characters that are replaced include:
Parameters: ctext(in)
htp.ps
The htp.ps hypertext procedure is the alias for the procedure htp.prints. The parameters are the
same for both procedures.
htp.s
The htp.s hypertext procedure generates HTML tags that specify text as being displayed in the
format where a line is drawn through the text. This display format may be useful for deemphasizing
certain text on a Web page.
Listing 7.41 displays the PL/SQL code example using the htp.s procedure, and Listing 7.42 shows
the HTML code generated by this procedure.
create or replace
procedure sproc as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.s Example');
htp.headClose;
htp.bodyOpen;
htp.print('This is a sample of normal text');
htp.nl;
htp.s('This is a sample of s text');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.s Example</H1>
</HEAD>
<BODY>
This is a sample of normal text
<BR>
<S>This is a sample of s text</S>
</BODY>
</HTML>
htp.sample
The htp.sample hypertext procedure generates a pair of HTML tags that mark a section of text as a
sequence of characters. The text is displayed exactly in the sequence it is typed.
Listing 7.43 displays a PL/SQL code example using the htp.sample procedure, and Listing 7.44
shows the HTML code generated by this procedure.
create or replace
procedure sample as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.sample Example');
htp.headClose;
htp.bodyOpen;
htp.sample('This is a test of the htp.sample procedure. Here are
some special characters to play with: $ % < & # *');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.sample Example</H1>
</HEAD>
<BODY>
<SAMP>This is a test of the htp.sample procedure. Here are some
special characters to play with: $ % < & # *</SAMP>
</BODY>
</HTML>
htp.small
The htp.small hypertext procedure generates HTML tags to mark a section of text with a small
font size. Using this procedure can help differentiate sections within a Web page.
Listing 7.45 displays a PL/SQL code example using the htp.small procedure, and Listing 7.46
shows the HTML code generated by this procedure
create or replace
procedure small as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.small Example');
htp.headClose;
htp.bodyOpen;
htp.print('This is a sample of text with normal-sized font');
htp.nl;
htp.small('This is a sample of text with small-sized font');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.small Example</H1>
</HEAD>
<BODY>
This is a sample of text with normal-sized font
<BR>
<SMALL>This is a sample of text with small-sized font</SMALL>
</BODY>
</HTML>
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.strike
The htp.strike hypertext procedure generates HTML tags that specify text as being
displayed in the strikethrough format. This is a good way to highlight text so that it
stands out on a Web page. Specifically, notice in Figure 7.25 that the text has a line
drawn through it.
Listing 7.47 displays a PL/SQL code example using the htp.strike procedure, and
Listing 7.48 shows the HTML code generated by this procedure.
create or replace
procedure strike as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.strike Example');
htp.headClose;
htp.bodyOpen;
htp.print('This is a sample of normal text');
htp.nl;
htp.strike('This is a sample of strikethrough text');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.strike Example</H1>
</HEAD>
<BODY>
This is a sample of normal text
<BR>
<STRIKE>This is a sample of strikethrough text</STRIKE>
</BODY>
</HTML>
htp.strong
The htp.strong hypertext procedure is functionally identical for most browsers to the
htp.bold hypertext procedure. Again, it is a way to emphasize text.
Listing 7.49 displays a PL/SQL code example using the htp.strong procedure and
Listing 7.50 shows the HTML code generated by this procedure.
create or replace
procedure strong as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.strong Example');
htp.headClose;
htp.bodyOpen;
htp.strong('This is a sample of strong-formatted text');
htp.nl;
htp.bold('This is a sample of bold-formatted text');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.strong Example</H1>
</HEAD>
<BODY>
<STRONG>This is a sample of strong-formatted text</STRONG>
<BR>
<B>This is a sample of bold-formatted text</B>
</BODY>
</HTML>
htp.sub
The htp.sub hypertext procedure generates HTML tags that mark text as a subscript.
Basically, it changes the text to a smaller font size.
htp.sup
The htp.sup hypertext procedure displays text as superscript. The font size of the text
is smaller than that presented by the procedure htp.sub.
htp.tableCaption
The htp.tableCaption hypertext procedure inserts a caption into the inserted table. The
caption is not required for a table and can be aligned at the top or bottom.
htp.tableClose
The htp.tableClose hypertext procedure closes an HTML table. This tag is generally
used when you are done displaying data from a table and you want to continue building
your Web page. There are no parameters related to this procedure.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.tableData
The htp.tableData hypertext procedure inserts data into an HTML table. HTML table data is organized
by cells, which comprise a row.
• cvalue—Defines the value to be inserted into the HTML table (varchar2). Default NULL.
• calign—Specifies how to align the value within the table cell (varchar2). Default NULL.
• cdp—Lets the parameter default to null (varchar2). Default NULL.
• crowspan—Indicates the number of rows to span in the table (varchar2). Rows can be
spanned by grouping cells that apply to several horizontal entries in the table. Default NULL.
• ccolspan—Indicates the number of columns to span in the table (varchar2). Span columns
when you want to group cells for more than one column in a table. The spanned columns could
fall under the same heading. Default NULL.
• cnowrap—Specifies that text will not wrap within the cell (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
Listing 7.51 displays a PL/SQL code example using the htp.tableData procedure, and Listing 7.52
shows the HTML code generated by this procedure. All proprietary information has been replaced with
an x.
create or replace
procedure s10b(host_name_in in varchar2) as
BEGIN
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 's10');
htp.htmlOpen;
htp.headOpen;
htp.title('s10');
htp.nl;
htp.nl;
for host_rec in (
select
rowid,
a.host_name,
a.ip_address,
a.cust_name,
a.os_type,
a.os_version,
a.oracle_csi_nbr,
a.dba_pager_nbr
from host a
where host_name = rtrim(host_name_in))
loop
htp.tableData(htf.anchor('update_host?my_rowid='||hostrec.rowid,
'modify this host'));
htp.print('Customer_name: ');
htp.formText('cust_name',10,50,host_rec.cust_name);
htp.nl;
htp.nl;
htp.nl;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
<HTML>
<HEAD>
<TITLE>s10</TITLE>
<H1>Oracle information database</H1>
<H1 ALIGN="C">Host Display</H1>
</HEAD>
<TD><A HREF="update_host?my_rowid=0000000F.0000.0005">Update this host
</A></TD>
<BR>
<BR>
Host Name:
<INPUT TYPE="text" NAME="host_name" SIZE="10" MAXLENGTH="50"
VALUE="xxxxxxx">
IP address:
<INPUT TYPE="text" NAME="ip_address" SIZE="20" MAXLENGTH="50"
VALUE="xxx.xxx.xxx.xx">
Customer_name:
<INPUT TYPE="text" NAME="cust_name" SIZE="10" MAXLENGTH="50"
VALUE="XXXXX">
Operating System:
<INPUT TYPE="text" NAME="os_type" SIZE="10" MAXLENGTH="50"
VALUE="Solaris">
Operating System version:
<INPUT TYPE="text" NAME="os_version" SIZE="10" MAXLENGTH="50"
VALUE="2.5">
Oracle CSI Number:
<INPUT TYPE="text" NAME="oracle_csi_nbr" SIZE="10" MAXLENGTH="50"
VALUE="1234567">
DBA pager number:
<INPUT TYPE="text" NAME="dba_pager_nbr" SIZE="10" MAXLENGTH="50"
VALUE="xxx-xxxx">
<BR>
<BR>
</FORM>
</BODY>
</HTML>
htp.tableHeader
The htp.tableHeader hypertext procedure creates a table header. There are several parameters that can
be passed to determine the characteristics of header text.
• cvalue—Defines the header text to be inserted into the HTML table (varchar2). Default
NULL.
• calign—Specifies how to align the header text within table cells (varchar2). Default NULL.
• cdp—Lets this parameter default to null (varchar2). Default NULL.
• crowspan—Indicates the number of rows to span in the table (varchar2). Rows can be
spanned by grouping cells that apply to several horizontal entries in the table. Default NULL.
• ccolspan—Identifies the number of columns to span in the table (varchar2). Span columns
when you want to group cells for more than one column in a table. The spanned columns would
fall under the same heading. Default NULL.
• cnowrap—Specifies that text will not wrap for the header (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
htp.tableOpen
The htp.tableOpen hypertext procedure opens an HTML table. Note that an HTML table is not
necessarily the same thing as an Oracle table, but Oracle tables are generally displayed on a Web page
using this tag.
• cborder—Indicates whether you want borders around each cell. This is the width of the
outside frame measured in pixels (varchar2). Default NULL.
• calign—Specifies how to align the table (varchar2). Default NULL.
• cnowrap—Specifies that the table is defined without text wrapping (varchar2). Default
NULL.
• cclear—Inserts a new line into the table (varchar2). Default NULL.
• cattributes—Attribute settings for HTML tags (varchar2). Default NULL.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
htp.tableRowClose
htp.tableRowOpen
The htp.tableRowOpen hypertext procedure inserts a row tag into an HTML table
within a Web page. There are certain alignment issues to be addressed for the table
rows.
htp.teletype
htp.title
The htp.title hypertext procedure is used to create a title section for a Web page. As
we recall, a title is the name of the page that appears on the Web browser icon when
the browser is minimized.
Parameters: ctitle(in)
• ctitle—Indicates the text displayed for the title on the Web document
(varchar2).
htp.ulistClose
The htp.ulistClose hypertext procedure generates an HTML tag to close a list of items
that are in no particular order (unordered list). The items will be marked with bullets to
help differentiate the items in the list. There are no parameters for this procedure.
Note: See procedure htp.ulistOpen for examples of the PL/SQL and HTML
code related to this procedure.
htp.ulistOpen
Listing 7.53 displays a PL/SQL code example using the htp.ulistOpen procedure, and
Listing 7.54 shows the HTML code generated by this procedure.
create or replace
procedure ulistprc as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer htp.ulistOpen Example');
htp.headClose;
htp.bodyOpen;
htp.ulistOpen;
htp.listItem('Ulist Item: Export the table');
htp.listItem('Ulist Item: Drop the table');
htp.listItem('Ulist Item: Create the table/indexes');
htp.listItem('Ulist Item: Import the data');
htp.ulistClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
<HTML>
<HEAD>
<H1>Oracle WebServer htp.ulistOpen Example</H1>
</HEAD>
<BODY>
<UL>
<LI>Ulist Item: Export the table
<LI>Ulist Item: Drop the table
<LI>Ulist Item: Create the table/indexes
<LI>Ulist Item: Import the data
</UL>
</BODY>
</HTML>
htp.variable
The htp.variable hypertext procedure generates an HTML tag that marks specified
text as a variable. As we know from our discussions about the CGI, these environment
variables are used for passing user input and other information between the browser
and Web server. This procedure highlights text (usually italicized) to represent a
variable name. It is strictly text presented on the Web page—nothing more.
htp.wbr
The htp.wbr hypertext procedure is used to generate an HTML tag that will insert a
line break into text defined with procedure htp.nobr (for no line breaking). There are
no parameters for this hypertext procedure.
Summary
In this chapter we have reviewed the hypertext procedures and functions provided by
Oracle WebServer that are built on top of the common HTML tags used to construct
Web documents. These functional modules of code simplify the task of tagging HTML
documents, making development on the Web a more productive process. Moving on to
Chapter 8, we will learn about a full suite of PL/SQL utilities included with Oracle
WebServer that are built on the hypertext procedures and functions found in this
chapter, and which enhance the functionality of Web documents.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 8
WebServer’s OWA Utilities
The OWA utilities are a set of procedures built on hypertext procedures and functions. These
commonly used procedures are designed to save the developer from writing code for basic processes.
There are several Oracle packages that contain OWA utilities. The source code for these packages is
found in $ORACLE_HOME/ows2/admin:
The parameters processed by the procedures and functions that comprise the OWA packages are
defined as being one of several data types. These would include the standard data types varchar2,
integer, and date, as well as other special types defined specifically for use by Oracle WebServer.
A cookie is a file or a data item left on your PC after you have connected to a Web page. In general,
a cookie allows WebServer to record information about which screens you have accessed, the name
of your internal userid, and other application-specific information. Prior to 1996, cookies were
generally sent to the server, but today cookies often reside on client PCs. When accessing an
unknown Web page, most savvy Web surfers refuse to allow the page to store a cookie on their PC
to avoid introducing a virus. Most cookies are set to expire after a specific date.
In any case, cookies are very useful for enabling an Oracle WebServer application to record
information about users’ previous visits to a Web page. Cookie files are generally transmitted to the
PC on an as-needed basis and are generally read from the PC when the Web page is accessed. The
following cookie utilities allow a WebServer developer to control the transmission of cookie files to
and from their Oracle server. Chances are, you already have some cookie files on your PC. For
example, here is the cookie file for the Netscape Web browser:
For Oracle’s WebServer, a cookie file can be used to remember the session information from each
user’s last visit to your Web page. Information, such as user preferences and the values for input
forms, can be kept in a cookie file. Following is a description of the OWA_COOKIE procedures and
functions.
OWA_COOKIE.GET
The owa_cookie.get function accepts a text string and converts it into a cookie file. For example:
Parameters: cname(in)
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
OWA_COOKIE.GET_ALL
The owa_cookie.get_all procedure returns all cookie name/value pairs from the
client’s browser associated with your WebServer session. This procedure returns an
array of the names and values of the cookies as they were processed, and a count of
the name/value combinations.
OWA_COOKIE.REMOVE
OWA_COOKIE.SEND
The owa_cookie.send procedure is used to send a cookie to a client station and must
be used with the HTTP header output of the OWA procedure.
The OWA Image Package assists in the handling of Web images. One of the key
aspects of Web image management is the management of image maps. When you use
an image map, you need to manage the image’s linked areas, called hotspots. The
OWA image functions can assist you in defining the coordinates of the image
hotspots. Unfortunately, the two OWA image functions do not work within Oracle
WebServer 2. Oracle Support indicates that they may work in Oracle WebServer 3.
OWA_IMAGE.GET_X
Parameters: xcoord(in)
OWA_IMAGE.GET_Y
Parameters: ycoord(in)
The OWA Init Package allows for the changing of constants that define the time zone
used by cookies. See the OWA Cookie Procedures And Functions section in this
chapter for more information about cookies.
Expiration dates used by cookies are defined in Greenwich Mean Time (GMT), and
should be reset to the time zone in which your Web page is running. This time zone
can be adjusted via one of two constants, depending on your circumstances. If your
time zone is recognized by Oracle WebServer (see Table 8.1), then you can set it using
the constant dbms_server_timezone. If you are located in an unrecognized time zone,
the constant dbms_server_gmtdiff can be used to specify the offset of your time zone
from GMT. The script used in this process is located at $ORACLE_HOME/ows2/
admin/pubinit.sql, where the constants can be defined as follows:
In this example, if you are located in the easternmost part of Siberia, you would set the
time zone to string BST.
If you need to set the number of hours that your time zone differs from GMT (a
positive number is used to set your time ahead of GMT and a negative number for
behind GMT), then set the following constant:
Once the constants have been reset in the pubinit.sql script, then re-create the
OWA_INIT package.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
The OWA Parms procedures and functions support the updating of database tables
from Web pages. Using PL/SQL arrays, which are tables of varchar2(2000) rows, is
essential for successfully processing the update requests.
Note: This package is not included with Oracle WebServer 2.0, but is
included with versions 2.1 and higher.
OWA_PARMS.GET
The owa_parms.get function retrieves the field names and values from a PL/SQL
array. These values can be placed in a record to be used in updating a table row.
• pname—Name of the field whose value will be retrieved from the PL/SQL
array (owa_parms.array).
OWA_PARMS.REGISTER
The owa_parms.register procedure loads a PL/SQL array with field names and
values. These names and values can be used for subsequent processing and are
indexed by binary integers.
OWA_PARMS_DEMO_FORM
The owa_parms_demo_form procedure is not a part of the OWA Parms package but
is included in the owa_parms.sql script as an example. The procedure submits a form
that shows how PL/SQL arrays are passed as associative arrays. The field name is
analyzed and the values related to this field name are processed in an iterative routine.
The OWA Pattern utilities manipulate data strings and include three different types of
operations: match, amatch, and change. The match procedures search a string for
either a string or pattern and return a boolean TRUE or FALSE. The amatch
procedures allow the user to specify where in a target string to search for a string or
pattern, and return the location where the search found a match. To replace the text
found in a string and return the number of substitutions made, the change procedures
should be used. For each of the manipulation procedures, there are wildcard characters
that can provide more options in defining the search strings. (See Table 8.2.)
Table 8.3 displays extensions that apply to the wildcards (except &) and text that
furthers search capabilities.
In the following example of how to use search string wildcards and extensions, we are
searching for the string urf in target string Surfing the Web.
The period (.) specifies to match any character except newline, and the plus sign (+)
instructs to include only 1 or more occurrences of the match.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
OWA_PATTERN.AMATCH (VERSION 1)
create or replace
procedure amatch1 as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_pattern.amatch Example');
htp.headClose;
htp.bodyOpen;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.2 shows the HTML code generated from the procedure shown in Listing 8.1.
Listing 8.2 HTML source code generated from the owa_pattern.amatch (version 1)
procedure.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_pattern.amatch Example</H1>
</HEAD>
<BODY>
Search a string from a starting point
<BR>
String Found
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.1.
Figure 8.1 The Web page example for owa_pattern.amatch (version 1).
OWA_PATTERN.AMATCH (VERSION 2)
OWA_PATTERN.AMATCH (VERSION 3)
The owa_pattern.amatch (version 3) function searches a target string for a matching string
beginning at a starting position in the target string. The location of the match is returned as
the number of positions from the beginning of the search string. When no match is found for
the pattern, a zero is returned. The optional parameter backrefs is used by this variation of
the function and is a PL/SQL table that holds each string in the target that matched the search
criteria.
OWA_PATTERN.AMATCH (VERSION 4)
OWA_PATTERN.CHANGE (VERSION 1)
The owa_pattern.change (version 1) function searches a target string for a string and
replaces it. The change functions and procedures can only search for strings and not patterns.
The output from this function is the number of revisions that resulted from the search.
Please Select
OWA_PATTERN.CHANGE (VERSION 2)
The owa_pattern.change (version 2) procedure searches a string for a string and replaces it. In
Listing 8.3, a string is searched for the string Sabres and is replaced with the string Bills. The
flags parameter is set to g, making a global replacement for all occurrences of the search pattern.
However, there is only one occurrence for this test. The search and replacement is successful,
which is validated by the before and after images of the target string displayed on the Web page.
create or replace
procedure change2 as
charstring varchar2(15);
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_pattern.change Example');
htp.headClose;
htp.bodyOpen;
owa_pattern.change(charstring,'Sabres','Bills','g');
htp.nl;
htp.print('After Image: ');
htp.print(charstring);
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.4 shows the HTML code generated from the procedure shown in Listing 8.3.
Listing 8.4 HTML source code created from the owa_pattern.change (version 2) procedure.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_pattern.change Example</H1>
</HEAD>
<BODY>
Search a string for a string and replace it
<BR>
Before Image:
Buffalo Sabres
<BR>
After Image:
Buffalo Bills
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.2.
Figure 8.2 The Web page example for owa_pattern.change (version 2).
OWA_PATTERN.CHANGE (VERSION 3)
The owa_pattern.change (version 3) function searches a multiple-line string for a string and
replaces it. The number of revisions that occur within the multi_line is an output of this
function.
OWA_PATTERN.CHANGE (VERSION 4)
The owa_pattern.change (version 4) procedure searches a multiple-line string for a string and
replaces it. In Listing 8.5, a multiple-line string is searched for the string Amerks and is to be
replaced with the string Americans.
Notice in the code that the mline variable is declared with the data type owa_text.multi_line,
which is standard for a multi_line variable. The search is successful and replaces the found text
as indicated on the Web page with the before and after images.
create or replace
procedure change4 as
charstring varchar2(45);
mline owa_text.multi_line;
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_pattern.change Example');
htp.headClose;
htp.bodyOpen;
owa_text.stream2multi(charstring,mline);
owa_pattern.change(mline,'Amerks','Americans','g');
htp.nl;
htp.print('After Image: ');
owa_text.print_multi(mline);
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.6 shows the HTML code generated from this procedure.
Listing 8.6 HTML source code for the procedure shown in Listing 8.5.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_pattern.change Example</H1>
</HEAD>
<BODY>
Search a multi_line for a string and replace it
<BR>
Before Image:
The Rochester Amerks are Calder Cup Champions
<BR>
After Image:
The Rochester Americans are Calder Cup Champions
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.3.
Figure 8.3 The Web page example for owa_pattern.change (version 2).
OWA_PATTERN.GETPAT
The owa_pattern.getpat procedure converts a string defined as varchar2 to the special data
type owa_pattern.pattern for use in pattern searching operations via the OWA Pattern
package.
Refer to the owa_pattern.match (version 4) section in this chapter for an example of the
owa_pattern.getpat procedure.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
OWA_PATTERN.MATCH (VERSION 1)
The owa_pattern.match (version 1) function searches a target string for a string and returns a boolean
TRUE or FALSE. In Listing 8.7, a string is searched for the string hal. The flags parameter is set to i,
which makes the search case-insensitive. Because the search is successful, the message The Search has
found a Match is displayed to the Web page, as shown in Figure 8.4.
Figure 8.4 The Web page example for owa_pattern.match (version 1).
create or replace
procedure match1 as
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_pattern.match Example');
htp.headClose;
htp.bodyOpen;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.8 displays the HTML code generated from the function shown in Listing 8.7.
Listing 8.8 HTML source code for the function shown in Listing 8.7.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_pattern.match Example</H1>
</HEAD>
<BODY>
Search a string for a string
<BR>
The Search has found a Match
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.4.
OWA_PATTERN.MATCH (VERSION 2)
The owa_pattern.match (version 2) function searches a target string for a pattern. A boolean TRUE or
FALSE will be returned from the function.
Note: A pattern is a PL/SQL table of 4-byte varchar2 strings that provides another way of
storing a regular string defined with the varchar2 data type. One of the reasons for wanting to
use a pattern for searching instead of a regular string is that the pattern can be an input or output
parameter. Using the pattern as an output would eliminate multiple parsing of the pattern when
the same pattern is passed to other owa_pattern calls.
OWA_PATTERN.MATCH (VERSION 3)
The owa_pattern.match (version 3) function searches a target string for a string and returns a boolean
TRUE or FALSE. This function also uses the parameter backrefs, which is a PL/SQL table of strings
that match the target string.
• backrefs—An output parameter that is a PL/SQL table that holds each string matched in the
target (owa_text.vc_arr).
• flags—Settings for interpreting the search criteria (varchar2). Default is NULL.
OWA_PATTERN.MATCH (VERSION 4)
The owa_pattern.match (version 4) function searches a target string for a pattern and returns a
boolean TRUE or FALSE. In Listing 8.9, a string is searched for the FAL. pattern. Notice that a period
was placed just after the three characters FAL, which is a wildcard token that will match any character
except newline. The search is successful because the flags parameter was set to allow for a case-
insensitive search. The message The Search has found a Matching Pattern is posted to the Web page to
validate the test. (See Figure 8.5.)
Figure 8.5 The Web page example for owa_pattern.match (version 4).
Note: There are two special data types used in this example for the parameters pat(owa_pattern.
pattern) and backrefs (owa_text.vc_arr).
create or replace
procedure match4 as
patstring owa_pattern.pattern;
backrefs owa_text.vc_arr;
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_pattern.match Example');
htp.headClose;
htp.bodyOpen;
owa_pattern.getpat('FAL.',patstring);
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.10 shows the HTML source code generated from the owa_pattern.match (version 4)
procedure shown in Listing 8.9.
Listing 8.10 The HTML source code for the function shown in Listing 8.9.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_pattern.match Example</H1>
</HEAD>
<BODY>
Search a string for a pattern
<BR>
The Search has found a Matching Pattern
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.5.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
OWA_PATTERN.MATCH (VERSION 5)
This function searches a target multi_line (multiple-line string) for a string and will return a boolean
TRUE or FALSE from the process. In Listing 8.11, the search is successful, finding the string base in
lines one and three of the multiple-line string. The Web page displays messages validating the success
of the search, as shown in Figure 8.6.
Figure 8.6 The Web page example for owa_pattern.match (version 5).
Note: Additional lines were added to the multi_line using the owa_text.add2multi procedure
and the row list (parameter rlist) was printed using the procedure owa_text.print_row_list.
Note: There are two special data types used in this example for the parameters mline
(owa_text.multi_line) and rlist(owa_text.row_list).
create or replace
procedure match5 as
charstring1 varchar2(50);
charstring2 varchar2(50);
charstring3 varchar2(50);
searchstr varchar2(5);
mline owa_text.multi_line;
rlist owa_text.row_list;
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_pattern.match Example');
htp.headClose;
htp.bodyOpen;
owa_text.stream2multi(charstring1,mline);
owa_text.add2multi(charstring2,mline,FALSE);
owa_text.add2multi(charstring3,mline,FALSE);
If owa_pattern.match(mline,searchstr,rlist) = TRUE
then htp.print('The Search has found a Matching String');
end if;
htp.nl;
htp.print('Print the line numbers which had a match in the
multi_line: ');
htp.nl;
owa_text.print_row_list(rlist);
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.12 shows the HTML code generated from the owa_pattern.match (version 5) procedure
shown in Listing 8.11.
Listing 8.12 The HTML source code for the function shown in Listing 8.11.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_pattern.match Example</H1>
</HEAD>
<BODY>
The Web page created from this code is depicted in Figure 8.6.
OWA_PATTERN.MATCH (VERSION 6)
The owa_pattern.match (version 6) function searches a target multi_line for a pattern, and a boolean
TRUE or FALSE will be returned. The line numbers in the multi_line that contain the matching
pattern will be stored in the row list using parameter rlist.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The OWA Text class of utilities is used primarily in conjunction with the OWA Pattern procedures
and functions, providing functionality for manipulating multiple lines of text and processing special
data types.
OWA_TEXT.ADD2MULTI
The owa_text.add2multi procedure allows for content to be added to a multi_line. In Listing 8.13,
the continue parameter is set to FALSE, which adds the new content to the multi_line as three new
lines rather than appending to the first line.
create or replace
procedure add2multi as
charstring1 varchar2(47);
charstring2 varchar2(47);
charstring3 varchar2(47);
charstring4 varchar2(47);
mline owa_text.multi_line;
begin
htp.htmlOpen;
htp.headOpen;
htp.header(1,'Oracle WebServer owa_text.add2multi Example');
htp.headClose;
htp.bodyOpen;
owa_text.stream2multi(charstring1,mline);
htp.print('Before Image of multi_line: ');
owa_text.print_multi(mline);
htp.nl;
owa_text.add2multi(charstring2,mline,FALSE);
owa_text.add2multi(charstring3,mline,FALSE);
owa_text.add2multi(charstring4,mline,FALSE);
htp.nl;
htp.print('After Image of multi_line: ');
owa_text.print_multi(mline);
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.14 shows the HTML code generated from the owa_text.add2multi procedure.
Listing 8.14 The HTML source code for the procedure shown in Listing 8.13.
<HTML>
<HEAD>
<H1>Oracle WebServer owa_text.add2multi Example</H1>
</HEAD>
<BODY>
Add content to a multi_line
<BR>
Before Image of multi_line:
This is a test of the Emergency Dating System.
<BR>
<BR>
After Image of multi_line:
This is a test of the Emergency Dating System.
If this had been a real emergency, you would
have been instructed where to tune in for more
information about your next date.
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.7.
OWA_TEXT.NEW_ROW_LIST
Parameters: rlist(out)
• rlist—Parameter normally used to contain a list of line numbers in the multi_line where
string matches were found from a search (owa_text.row_list).
OWA_TEXT.PRINT_MULTI
The owa_text.print_multi procedure uses the htp.print procedure behind the scenes to print the
strings in a multi_line. A multi_line is a multiple-line string defined with data type owa_text.
multi_line.
Parameters: mline(in)
OWA_TEXT.PRINT_ROW_LIST
The owa_text.print_row_list procedure uses the htp.print procedure to print a list of the line
numbers in a multi_line where matches were found from a search. In the example, the special data
type owa_text.row_list is used to define the rlist parameter.
Parameters: rlist(in)
OWA_TEXT.STREAM2MULTI
The owa_text.stream2multi procedure converts very long strings (>= 32 K) to the multi_line data
type.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The OWA Util package of procedures utilizes the hypertext functions and hypertext procedures (htf and htp,
respectively) bundled with Oracle WebServer. They can be used to enhance the development of HTML to
perform numerous tasks, such as formatting documents, forms, and image maps.
OWA_UTIL.GET_CGI_ENV
The owa_util.get_cgi_env function returns the value of a CGI environment variable. An example of such a
variable is path_translated. If the value of the variable is not defined, then a NULL value is returned.
Parameters: cname(in)
OWA_UTIL.GET_OWA_SERVICE_PATH
The owa_util.get_owa_service_path function returns the name of the currently active path, which includes
the virtual path, the DCD (Database Connection Descriptor), and the PL/SQL Agent executable. The format
for the active path returned is /ows-bin/DCD_name/owa/. The currently active path will not include the
DCD_name when it defaults to the name of the owa_default_service, which is the user PL/SQL Agent access
service. There are no parameters for this function.
An example of the use of this utility can be found in the example for owa_util.showsource, where a form is
opened by concatenating the active path to the form name.
OWA_UTIL.HTTP_HEADER_CLOSE
OWA_UTIL.MIME_HEADER
The owa_util.mime_header procedure changes the default MIME header returned by the PL/SQL Agent.
Remember that MIME identifies the type of document returned to the browser. The parameter mime_header
must precede all htp.print and htp.prn calls to allow the default MIME to be changed. Setting the parameter
bclose_hdr to TRUE will send two newlines and close the HTTP header. Otherwise, setting it to FALSE
will not close the HTTP header because only one newline is sent.
• mime_type—Default MIME type that identifies the content of the files (varchar2).
• bclose_hdr—Setting to determine if the HTTP header should be closed or not (boolean). Default is
TRUE.
OWA_UTIL.PRINT_CGI_ENV
The owa_util.print_cgi_env procedure prints the values of all the CGI environment variables that are
processed between the PL/SQL Agent and the PL/SQL procedures. Remember, the CGI environment
variables are used for communication purposes regardless of whether CGI or WRB is used to process the
requests. Printing these variables can be tremendously helpful in testing the functionality of your Web pages.
For instance, the variables in Listing 8.15 indicate a Gateway_Interface using CGI/1.1 and a Script_Name
of /ows-bin/owa (which is the currently active path). A few variables in the following examples have been
intentionally blanked-out to protect proprietary information. There are no parameters for this procedure.
create or replace
procedure printcgienv as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver owa_util.print_cgi_env');
htp.header(1,'Oracle WebServer owa_util.print_cgi_env Example');
htp.headClose;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 'printcgiform');
htp.FormClose;
owa_util.print_cgi_env;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.16 shows the HTML code generated from the owa_util.print_ cgi_env procedure.
Listing 8.16 The HTML source code for the procedure shown in Listing 8.15.
<HTML>
<HEAD>
<TITLE>Oracle Webserver owa_util.print_cgi_env</TITLE>
<H1>Oracle WebServer owa_util.print_cgi_env Example</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/printcgiform" METHOD="POST">
ENTER Hostname:
<INPUT TYPE="text" NAME="Hostname" SIZE="10" MAXLENGTH="50">
<BR>
</FORM>
SERVER_SOFTWARE = Oracle_Web_listener2.0/1.20in2<BR>
SERVER_NAME = xxxxxxx<BR>
GATEWAY_INTERFACE = CGI/1.1<BR>
REMOTE_HOST = <BR>
REMOTE_ADDR = xxx.xxx.xx.xx<BR>
AUTH_TYPE = <BR>
REMOTE_USER = <BR>
REMOTE_IDENT = <BR>
HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*<BR>
HTTP_USER_AGENT = Mozilla/3.0 (Win16; I)<BR>
SERVER_PROTOCOL = HTTP/1.0<BR>
SERVER_PORT = 8111<BR>
SCRIPT_NAME = /ows-bin/owa<BR>
PATH_INFO = /printcgienv<BR>
PATH_TRANSLATED = /u01/dba/oracle/app/oracle/product/7.3.2/ows2/doc/
printcgienv<BR>
HTTP_REFERER = <BR>
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.8.
OWA_UTIL.REDIRECT_URL
The owa_util.redirect_url procedure redirects the processing of a URL. As in previous examples, the URL
may represent a Web page or a program to be executed. This procedure call must precede all htp.print and
htp.prn calls to allow the redirect by the PL/SQL Agent to process successfully. The parameter bclose_hdr
is defined with the boolean data type. If it is set to TRUE, bclose_hdr will send two newlines and close the
HTTP header. If it is set to FALSE, the HTTP header stays open because only one newline is sent.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
OWA_UTIL.SHOWPAGE
The owa_util.showpage procedure generates the HTML source code for a static Web page (forms won’t
be generated) from the output of a PL/SQL procedure and can be accessed in the future as a standard
HTML document. This procedure can be executed from SQL *Plus, SQL*DBA, or ServerManager and
must use an htp procedure and/or htf function to generate HTML source code. The HTML code is
generated into the spool file specified as part of the process. There are no parameters for this procedure.
An example of generating the HTML for procedure static through SQL*Plus is shown in Listing 8.17.
SQL> exit
OWA_UTIL.SHOWSOURCE
The owa_util.showsource utility procedure prints the source code of a PL/SQL package, procedure, or
function. This can be very helpful when you want an easy way to display your code while developing
your applications.
Parameters: cname(in)
• cname—Name of the package, procedure, or function whose source code will be displayed
(varchar2).
create or replace
procedure showsrc as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver showsrc');
htp.header(1,'Oracle WebServer owa_util.showsource(cname) Example');
htp.headClose;
htp.bodyOpen;
owa_util.showsource('formimage');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.19 shows the HTML code generated from the owa_util.showsource procedure.
Listing 8.19 The HTML source code generated from the owa_util.showsource procedure.
<HTML>
<HEAD>
<TITLE>Oracle Webserver showsrc</TITLE>
<H1>Oracle WebServer owa_util.showsource(cname) Example</H1>
</HEAD>
<BODY>
<H1>Source code for FORMIMAGE</H1>
<PRE>
procedure formimage as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver formImage');
htp.header(1,'Oracle WebServer htp.formImage Examples');
htp.headClose;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's00');
htp.print('Click on the Image to submit Form');
htp.FormImage('BobPic','/ows-img/papaj.gif');
htp.nl;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
</PRE>
<HR>
This page was produced by the
<B>Oracle Web Agent</B> on October 14, 1996 03:42 PM<BR>
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.9.
OWA_UTIL.SIGNATURE (VERSION 1)
The owa_util.signature (version 1) utility procedure creates a signature line at the bottom of the
document to timestamp the page. This feature will assist you in determining when a page was created.
There are no parameters for this procedure.
create or replace
procedure signa0 as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver owa_util.signature');
htp.header(1,'Oracle WebServer owa_util.signature Example');
htp.headClose;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 'sigform');
htp.FormClose;
owa_util.signature;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 8.21 shows the HTML code generated from the owa_util.signature (version 1) utility procedure.
Listing 8.21 The HTML source code generated from the procedure shown in Listing 8.20.
<HTML>
<HEAD>
<TITLE>Oracle Webserver owa_util.signature</TITLE>
<H1>Oracle WebServer owa_util.signature Example</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/sigform" METHOD="POST">
Click on the Image to submit Form
<INPUT TYPE="image" NAME="flamingo" SRC="/ows-img/flamingo.gif">
<BR>
</FORM>
<HR>
This page was produced by the
<B>Oracle Web Agent</B> on October 15, 1996 08:37 AM<BR>
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.10.
Figure 8.10 The Web page example for owa_util.signature (version 1).
OWA_UTIL.SIGNATURE (VERSION 2)
The owa_util.signature (version 2) utility procedure creates a signature line at the bottom of the
document that will timestamp the page. In addition, it will include a hypertext link that allows the source
code to be viewed for this page.
Parameters: cname(in)
• cname—Name of the procedure displaying the source code when a hypertext link is clicked on
(varchar2).
create or replace
procedure signa1 as
begin
htp.htmlOpen;
htp.headOpen;
htp.title('Oracle Webserver owa_util.signature(cname)');
htp.header(1,'Oracle WebServer owa_util.signature(cname) Example');
htp.headClose;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 'sigform');
htp.FormClose;
owa_util.signature('signa1');
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select Listing 8.23 displays the HTML code generated from the owa_util.signature (version 2) utility procedure.
Listing 8.23 The HTML source code generated from the owa_util.signature (version 2) utility procedure.
<HTML>
<HEAD>
<TITLE>Oracle Webserver owa_util.signature(cname)</TITLE>
<H1>Oracle WebServer owa_util.signature(cname) Example</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/sigform" METHOD="POST">
Click on the Image to submit Form
<INPUT TYPE="image" NAME="flamingo" SRC="/ows-img/flamingo.gif">
<BR>
</FORM>
<HR>
This page was produced by the
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/ch08/286-290.html (1 of 5)4/03/2005 6:16:01
Oracle Databases on the Web:WebServer's OWA Utilities
The Web page created from this code is depicted in Figure 8.11.
Figure 8.11 The Web page example for owa_util.signature (version 2).
Clicking on the hypertext link View PL/SQL source code will display the Web page shown in Figure 8.12.
OWA_UTIL.STATUS_LINE
A call to the owa_util.status_line procedure returns an HTTP status code to the browser. This call must precede all htp.print and htp.prn
calls in order for the status code to be sent as part of the HTTP header. Otherwise, it would be assumed to be content data. The HTTP header
can be closed by setting the parameter bclose_hdr to TRUE, which causes two newlines to be sent.
OWA_UTIL.TABLEPRINT
The owa_util.tableprint procedure displays an Oracle table in a Web page. This procedure is very easy to call and use, but it will not support
tables with long raw columns. It returns a TRUE or FALSE boolean, indicating if there are additional rows remaining beyond the value
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/ch08/286-290.html (2 of 5)4/03/2005 6:16:01
Oracle Databases on the Web:WebServer's OWA Utilities
In addition, this utility can specify individual columns to be displayed. For example:
This call would display only the columns called table_name, owner, and tablespace_name in the DBA_TABLE table.
htp.bodyOpen;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
Listing 8.25 shows the HTML generated from the owa_util.tableprint procedure.
Listing 8.25 The HTML source code generated from the owa_util.tableprint procedure.
<HTML>
<BODY>
<PRE>
-----------------------------------------------------------------------------------------------
| HOST_NAME | IP_ADDRESS | CUST_NAME | OS_TYPE | OS_VERSION | ORACLE_CSI_NBR | DBA_PAGER_NBR |
-----------------------------------------------------------------------------------------------
| | | | | | | |
-----------------------------------------------------------------------------------------------
</PRE>
<BR>
<BR>
</FORM>
</BODY>
</HTML>
The Web page created from this code is depicted in Figure 8.13.
Figure 8.13 The Web page example for the owa_util.tableprint procedure.
Summary
The OWA utilities described in this chapter add another dimension to the functionality of the hypertext procedures and functions included
with Oracle WebServer. Web application developers have been given numerous options to enhance the usefulness and capabilities of their
applications. Effective and efficient interaction between the Web and corporate data repositories will further the benefits to business
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/ch08/286-290.html (4 of 5)4/03/2005 6:16:01
Oracle Databases on the Web:WebServer's OWA Utilities
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 9
Oracle WebServer And PL/SQL
While many books have been written about programming with PL/SQL, this chapter is
devoted to the PL/SQL statements commonly used when creating Web pages for
Oracle WebServer. As we discussed in the previous chapter, a standard library of
HTML function calls are used to create the Web screen images, but these calls are
usually embedded within PL/SQL code.
Like most procedural languages, PL/SQL is compiled prior to runtime, and Oracle
allows for the precompiled executables to be stored procedures in a database. The
general construct of PL/SQL code is the block. All blocks within PL/SQL contain
three sections: Declare, Begin, and Exception.
PL/SQL is a highly structured language that consists of three primary sections: the
Declare section, the Begin section, and the Exception section. Within the first two
main sections, Declare and Begin, we find the majority of syntax of the PL/SQL
language.
Declare Section
The Declare section always begins with the word declare and ends with the word
begin. The Declare section defines the local variables to be referenced within the
program. The Declare section consists of variable and cursor declarations.
Variable Declaration
Variable declarations include all string, numeric, and binary types. The following
declarations are examples of scalar declarations:
• cust_num—INTEGER(4) := 100;
• person_num—custnum%type;
• tran_amount—CONSTANT NUMBER(4,2) := 100;
Note: The second declaration states that person_num has the same definition
as the cust_num variable. This shorthand syntax is the equivalent of the
COBOL redefines clause.
Cursor Declaration
Looking at the declaration section, it is impossible to tell if the cursor declaration will
retrieve a single row or multiple rows from an Oracle database. Listing 9.1 shows an
example of a cursor declaration from a WebServer stored procedure.
create or replace
procedure s10(host_name_in in varchar2) as
. . .
cursor c1 is
select
responsibility,
a.dba_name,
dept_name,
phone_nbr,
e_mail,
office_hrs,
home_phone_nbr
from dba_host a, dba b
where host_name = rtrim(host_name_in)
and
a.dba_name = b.dba_name;
host_rec c1%ROWTYPE;
BEGIN
htp.bodyOpen;
. . .
Next, we see the section that starts after the begin statement. This section is called the
executable section of PL/SQL, and this is where the main PL/SQL processing takes
place. This section is analogous to the Procedure Division in a COBOL program. The
main processing takes place within the executable section, and includes all of the
processing necessary to build and display the WebServer page for the end user.
Looping In PL/SQL
With Oracle WebServer, there are two loop structures available when you need to
retrieve a series of rows from a table and display the results on a Web page. While PL/
SQL supports for loops, while loops, and loop-until-exit structures, WebServer
developers most commonly use for loops or loop-until-exit to retrieve Oracle rows
and display them on a Web page. Listing 9.2 shows a WebServer example that creates
a checkbox list that contains all of the column names in the dba_tables view.
create or replace
procedure formcheckbox (tab_name in varchar2) is
cursor cols is
select
column_name
from
dba_tab_columns
where
table_name = upper(tab_name);
BEGIN
. . . .
end loop;
. . . .
end;
In Listing 9.2, we see that a cursor called cols is declared and referenced in the for
loop, such that each row returned (in this case, the column_names from the
dba_tables view) is mapped into a checkbox using the htp.formCheckbox call.
Also, PL/SQL can be used to set a loop-until-exit loop, where the PL/SQL code must
expressly request an exit from the loop. The basic syntax of the PL/SQL loop-until-
exit is:
counter := 0;
loop
If counter > 100 then exit;
end if;
counter := counter + 1;
end loop;
PL/SQL provides several methods for exiting a loop-until-exit loop. In the following
example, the PL/SQL exit when is used to terminate the loop:
fetch c1 into. ..
exit when c1%NOTFOUND;
end loop
close c1
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select In Oracle WebServer, the PL/SQL loop-until-exit structure can be used to retrieve a series of rows from
an Oracle table. In Listing 9.3, multiple rows are selected from the table called DBA and displayed on a
Web page.
create or replace
procedure s10(host_name_in in varchar2) as
responsibility varchar2(20);
dba_name varchar2(20);
dept_name varchar2(20);
phone_nbr varchar2(20);
e_mail varchar2(20);
office_hrs varchar2(20);
home_phone_nbr varchar2(20);
counter integer := 0;
cursor c2 is
select
responsibility,
a.dba_name,
dept_name,
phone_nbr,
e_mail,
office_hrs,
home_phone_nbr
from dba_host a, dba b
where host_name = rtrim(host_name_in)
and
a.dba_name = b.dba_name;
dba_rec c2%ROWTYPE;
BEGIN
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's10');
htp.htmlOpen;
htp.headOpen;
htp.title('s10');
htp.header(1,'Oracle information database');
htp.header(1,'Host Display','C');
htp.headClose;
htp.header(2,'DBA name Responsibility phone e-mail
office_hrs home phone : ');
htp.nl;
open c2;
loop
counter := counter + 1;
fetch c2 into dba_rec;
EXIT WHEN c2%NOTFOUND;
htp.FormText('dba_name'||counter,10,50,dba_rec.dba_name);
htp.FormText('responsibility'||counter,10,50,dba_rec.responsibility);
htp.FormText('dba_phone'||counter,10,50,dba_rec.phone_nbr);
htp.FormText('dba_e_mail'||counter,30,50,dba_rec.e_mail);
htp.FormText('dba_office_hrs'||counter,10,50,dba_rec.office_hrs);
htp.FormText('home_phone_nbr'||counter,10,50,dba_rec.home_phone_nbr);
htp.nl;
htp.nl;
end loop;
close c2;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
As objects such as stored procedures and triggers become more popular, more application code will move
away from external programs and into the database engine. Oracle has been encouraging this approach in
anticipation of the object-oriented features of Oracle version 8. However, the Oracle DBA must be
conscious of the increasing memory and disk storage demands of stored procedures, and carefully plan for
the days when all of the database access code resides within the database.
Today, most Oracle databases have only a small amount of code in stored procedures, but this is rapidly
changing. There are many compelling benefits to putting all Oracle SQL inside stored procedures. These
benefits include:
• Better performance—Stored procedures are loaded once into the SGA and remain there unless
they become paged out. Subsequent executions of the stored procedure are far faster than external
code.
• Coupling of data with behavior—Relational tables can be coupled with the behaviors associated
with them by using naming conventions. For example, if all behaviors associated with the employee
table are prefixed with the table name (e.g., EMPLOYEE.hire,EMPLOYEE.give_raise), then the
data dictionary can be queried to list all behaviors associated with a table (e.g., select * from
dba_objects where owner = ‘EMPLOYEE’) and code can be readily identified and reused.
• Isolation of code—Because all SQL is moved out of the external programs and into stored
procedures, the application programs become nothing more than calls to stored procedures. As
such, it becomes very simple to swap out one database and swap in another.
• Encapsulation—Code resides in the database instead of in external programs. With the proper use
of Oracle packages, stored procedures can be logically grouped together into a cohesive framework
of SQL statements.
• More flexibility—By keeping all database access inside Oracle packages, the applications contain
no SQL and become little more than a set of calls to the stored procedures. As such, the application
is insulated from the database, and it becomes very easy to migrate the application to another
platform or database product.
Note: Oracle System Global Area (SGA) is one of the foremost reasons why stored procedures
function faster than traditional code. After a procedure has been loaded into the SGA, it will remain
there until it is paged out of memory. Items are paged out based on a least-recently-used algorithm.
Once loaded into the RAM memory of the shared pool, the procedure will execute very quickly. The
trick is to prevent pool-thrashing while many procedures compete for a limited amount of shared
pool memory.
Oracle also provides a construct called a package. Essentially, a package is a collection of functions and
stored procedures that can be organized in a variety of ways. For example, functions and stored procedures
for employees can be logically grouped together in an employee package as follows:
END employee;
Here, we have encapsulated all employee behaviors into a single package that will be added to Oracle’s
data dictionary. If we force our programmers to use stored procedures, the SQL moves out of the external
programs and the application programs become nothing more than a series of calls to Oracle stored
procedures.
Note: For Oracle WebServer, it is a good idea to use a package to encapsulate all stored procedures
associated with a specific Web page. For example, Web page display, update, and delete procedures
could be combined into a single package, and the package name would be the name of the Web page.
Basic GO
Please Select
Tuning PL/SQL
PL/SQL is commonly used within Oracle’s SQL*Forms application framework. Recently, the
popularity of PL/SQL for non-SQL*Forms applications has re-emerged because of the benefits of
using Oracle stored procedures—which must be written with PL/SQL. PL/SQL offers the standard
language constructs including looping, if statement structures, assignment statements, and error
handling.
However, there are several problems with PL/SQL, each of which warrants special attention. PL/SQL
offers two types of SQL cursors, the explicit cursor and the implicit cursor. Explicit cursors are
manually declared in the PL/SQL:
DECLARE
CURSOR C1 IS
select last_name
from customer
where
cust_id = 1234;
However, it is possible to issue the SQL statement directly in PL/SQL without specifying the cursor
name. When this happens, Oracle opens an implicit cursor to handle the request. Implicit cursors
create a tremendous burden for Oracle, as the implicit cursor must always reissue a fetch command to
ensure that only a single row was returned by the query. This will double the amount of fetch
statements for the query. The moral is simple: Always be sure that you declare all cursors in your PL/
SQL.
Most savvy Oracle developers are aware that PL/SQL allows certain types of correlated subqueries to
run much faster than a traditional Oracle SQL query. For example, consider a situation where a bank
maintains two tables: a GENERAL_LEDGER table and a TRANSACTION table. At the end of the
banking day, each check in the TRANSACTION table is applied to the GENERAL_LEDGER table,
making the requisite deductions from the account_balance column. Furthermore, let’s assume that
the GENERAL_LEDGER table contains 100,000 rows and the TRANSACTION table processes
5,000 checks each day.
A traditional SQL query to accomplish the updating of the account_balance column of the
update GENERAL_LEDGER
set account_balance = account_balance -
(select check_amount from TRANSACTION
where
TRANSACTION.account_number = GENERAL_LEDGER.account_number)
where
exists
(select 'x' from TRANSACTION
where
TRANSACTION.account_number = GENERAL_LEDGER.account_number);
As you may recall, a correlated subquery involves executing the subquery first and then applying the
result to the entire outer query. In this case, the inner query will execute 5,000 times, and the outer
query is executed once for each row returned from the inner query. This Cartesian product problem
has always been a problem for correlated subqueries.
Now, consider the identical query written in PL/SQL, as shown in Listing 9.5.
DECLARE
CURSOR c1 is
select account_number,
check_amount
from TRANSACTION ;
keep_account_number number;
keep_check_amount number;
BEGIN
OPEN C1;
LOOP
fetch C1 into keep_account_number, keep check_amount;
exit when C1%NOTFOUND;
update GENERAL_LEDGER
set account_balance = account_balance - keep_check_amount
where account_number = keep_account_number;
END LOOP;
END;
In Listing 9.5 we see that each check amount is retrieved in a separate transaction and fetched into
cursor C1. For each check_amount, the balance is applied to the GENERAL_LEDGER row, one at
a time.
As we know from previous chapters, PL/SQL is created inside Oracle stored procedures. A stored
procedure may accept parameters if the Web page is passing a value to a subsequent Web page, as
follows:
http://www.oracle.com:8880/ows-bin/owa/customer.entry?customer=IBM
In this example, the package called customer is scanned to invoke a procedure called entry. The
entry procedure is then invoked with the input parameter customer set to the value IBM. If we take a
look at customer.entry, it should become clear how the variables are passed into the stored
procedure. The entry procedure is defined to accept a parameter called customer, as seen in the
following code:
create or replace
package customer as
procedure entry;
end;
/
show errors
end;
So, it appears that the name of the parameter and the value of the parameter must be specified in the
URL that calls the WebServer page. How then, do we get these values into the URL call? If we start
by taking a look at the following native HTML, we can see how the HTML <INPUT> tag can be used
to accept a value for the customer parameter. We can also see that the <FORM> tag is used to specify
the URL for the target WebServer page:
<FORM METHOD="POST"
ACTION="http://www.oracle.com:8880/ows-bin/owa/customer.entry">
When using WebServer, the following code could be used to create an input form so the user can enter
the customer name and an anchor to transfer to the customer.entry page when the anchor was
mashed:
To complete the illustration, look at how the customer.entry procedure might appear. Here we see a
simple process where customer is received and used to retrieve a single row from the
CUSTOMER_TABLE. The htp.print command is then used to display the number_of_orders
column.
Now that we understand how parameters are initially passed to a Web page, let’s take a look at how
data items are passed between Web pages in an Oracle application.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Passing Parameters Between PL/SQL Stored Procedures
Another time parameters are passed to a PL/SQL stored procedure is when an update routine is called
from a WebServer page. When using WebServer, it is customary to pass the rowid of the row to be
changed and a list of all the row values to an update procedure. This update procedure will check to
ensure that the row has not changed since it was originally retrieved (we are not holding locks), update
the row, check the return code, and return the appropriate message to the originating Web page.
In the following example, a single row with seven columns is retrieved from Oracle. Also, note that the
first item in the select statement grabs the rowid for the row.
Now that we have the rowid, we can look at how the rowid can be passed as a parameter to an update
routine. Essentially, PL/SQL allows for two methods:
htp.tabledata(htf.anchor('update_host?my_rowid='||host_rec.rowid,
'Update this host'));
• Store the rowid using htp.formhidden, and transfer to the update routine using htp.
formsubmit:
htp.formhidden('my_rowid', my_rowid);
htp.tableOpen;
formtext('host name ', 'host_name', hostrec.host_name);
formtext('IP address ', 'ip_address', hostrec.ip_address);
htp.tableClose;
To see how each method works, let’s examine a complete stored procedure that uses htp.anchor to
transfer to the update routine with the rowid of the row that will be updated. Listing 9.6 displays the use
of htp.anchor to pass a rowid to an update procedure.
create or replace
procedure s10a(host_name_in in varchar2) as
BEGIN
htp.htmlOpen;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's10');
htp.headOpen;
htp.title('s10');
for host_rec in (
select
rowid,
host_name,
ip_address,
cust_name,
os_type,
os_version,
oracle_csi_nbr,
dba_pager_nbr
from host
where host_name = rtrim(host_name_in))
loop
htp.tabledata(htp.anchor('update_host?my_rowid='||host_rec.rowid,
'Update this host'));
htp.nl;
htp.nl;
htp.print('Customer_name: ');
htp.FormText('cust_name',10,50,host_rec.cust_name);
htp.FormText('oracle_csi_nbr',10,50,host_rec.oracle_csi_nbr);
htp.nl;
htp.nl;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
It is important to note how the rowid is passed to the update routine. In Listing 9.6, the htp.anchor tag
has the name of the routine (update_host) concatenated with the rowid of the current row. The current
row was retrieved from the Oracle database and placed into the variable named my_rowid.
Of course, there are many ways to accomplish this type of parameter passing, and this text does not
have enough pages to illustrate every possible technique. Another popular method for passing
parameters to a procedure is to use the htp.formhidden command. To illustrate, consider Listing 9.7.
Listing 9.7 Using htp.formhidden with htp.formsubmit to pass a rowid to a stored procedure.
create or replace
procedure
update_host (my_rowid in rowid, msg in varchar2 default NULL) is
hostrec host%rowtype;
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.title('Test');
htp.headClose;
htp.bodyOpen;
htp.tableOpen;
formtext('host name ', 'host_name', hostrec.host_name);
formtext('IP address ', 'ip_address', hostrec.ip_address);
htp.tableClose;
htp.formReset;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
In Listing 9.7, we see that the rowid is saved by calling htp.formhidden, while the transfer to the
update routine is handled by htp.formsubmit. The htp.formsubmit statement in Listing 9.7 displays
two buttons: Update and Delete. When either of these buttons is pressed, the do_update routine is
called because it was specified in the htp.formopen statement.
Now, you are probably asking yourself, “We have passed the rowid, but what about the column data
that will be updated?” As we know, in PL/SQL, every parameter passed to a procedure must be defined
in the Declare section. For rows that contain dozens of columns, it can be very cumbersome to write an
update routine that accepts a parameter for each column to be updated. For example, the routine shown
in Listing 9.8 could be used to update a customer table.
create or replace
procedure
update_customer (my_rowid in rowid,
customer_name_parm in varchar2,
customer_street_parm in varchar2,
customer_zip_parm in integer,
customer_city_parm in varchar2,
customer_state_parm in varchar2,
customer_status_parm in varchar2
msg in varchar2 default NULL) is
hostrec customer%rowtype;
BEGIN
htp.htmlOpen;
. . .
update customer
set
customer_name = customer_name_parm,
customer_street = customer_street_parm,
customer_city = customer_city_parm,
customer_zip = customer_zip_parm,
customer_state = customer_state_parm,
customer_status = customer_status_parm
where
rowid = my_rowid;
. . .
htp.htmlClose;
end;
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select The problem of passing large numbers of input parameters becomes even more confounding when we are
passing multiple rows of data to a PL/SQL routine for updating. Fortunately, Oracle has provided a package
called owa_parms to simplify the passing of parameters between WebServer pages. The owa_parms utility
allows the column values to be stuffed into a single array and passed as an associative array, all within a single
parameter.
Note: For further details about owa_parms, see Chapter 8, WebServer’s OWA Utilities.
Here’s how owa_parms works. When a row is retrieved from Oracle, the owa_parms.register procedure is
used to store all of the values into a single associative array. The name of this array is then manipulated in the
PL/SQL stored procedure that performs the updating. In PL/SQL, we can create user-defined data types, and
these data types can be a single value, a list of values, or an array of values.
In Listing 9.9, htp.formhidden is called once for each column displayed on the Web page. Note the use of a
small procedure called formfield. Each time the formfield procedure is called, the variable is displayed on the
Web page (using htp.tableData) and the column values are passed using the htp.formhidden procedure.
Listing 9.9 Passing table data into an associative array for passing to other procedures.
create or replace
procedure formfield (p_label in varchar2,
p_name in varchar2,
p_value in varchar2) is
BEGIN
htp.tableRowOpen;
htp.tableData (p_label);
htp.tableData(htf.formHidden('p_name', p_name)||
htf.formText(p_value, 10, 50, cvalue => p_value));
htp.tableRowClose;
end;
create or replace
procedure update_form (host_name_in in varchar2) is
BEGIN
htp.formOpen('do_update');
for host_rec in (
select
rowid,
host_name,
ip_address,
cust_name,
os_type,
os_version,
oracle_csi_nbr,
dba_pager_nbr
from host
where host_name = rtrim(host_name_in))
loop
htp.tableData(htf.anchor('update_host?my_rowid='||host_rec.rowid,
'Update this host'));
htp.nl;
htp.nl;
htp.nl;
htp.nl;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors;
Figure 9.1 displays the Web page generated from the code in Listing 9.9.
As we can see, once the values are stored in the array, they can be passed to another procedure where they can
be interrogated and used to update the Oracle database. To see how this works, take a look at Listing 9.10,
which shows how the receiving routine accepts the array.
procedure update_customer (
p_rowid in rowid,
p_name in owa_parms.array,
p_values in owa_parms.array)
is
BEGIN
owa_parms.register (p_name, p_values);
...
...
end;
This routine accepts three parameters: the rowid of the row to be updated, an array of type owa_parms.array
that contains the name of the array item, and another array of type owa_parms.array that holds the list of
column values. The owa_parms.register function is then invoked.
We are now ready to update our Oracle database with the new column values. Let’s start by examining the
procedure that receives the parameters and issues the sql update statement, as shown in Listing 9.11.
Listing 9.11 The process of updating Oracle based on data in an associative array.
procedure do_update (
p_rowid in rowid,
p_name in owa_parms.array,
p_values in owa_parms.array)
is
BEGIN
owa_parms.register (p_name, p_values);
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
Now, let’s take a careful look at what is happening in the procedure shown in Listing 9.11. We see that each
column of the desired row is being assigned to the value of owa_parms.get(‘name_value’). The owa_parms.
get function accepts the name of an array item and returns the value associated with the name when it was
stored using the owa_parms.register procedure. To thoroughly understand how the owa_parms package
works, you may want to take a look at the source code for the package. It is stored in the file owa_parms.sql.
Note: The owa_parms package is only available with WebServer version 2.1 and later. If you do not
have it, you can download it from http://www.oracle.com. Once downloaded, the package should reside
on your WebServer host in $ORACLE_HOME/ows2/admin/owa_ parms.sql.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Managing Oracle I/O Using PL/SQL And WebServer
While input/output operations are very similar between PL/SQL in SQL*Forms and WebServer, there are some
important differences, especially in the manner in which Oracle data is displayed to the end user. This section
will explore various ways of performing input against your Oracle database and mapping the retrieved data
back to your Web page.
When Oracle is asked to return a single row value from a database, it is a simple matter to display the columns
on a Web page. For example, consider the PL/SQL code shown in Listing 9.12, where a single row is returned
from the host table and displayed on a Web page.
create or replace
procedure s10a(host_name_in in varchar2) as
BEGIN
htp.htmlOpen;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's10');
htp.headOpen;
htp.title('s10');
for host_rec in (
select
host_name,
ip_address,
cust_name,
os_type,
os_version,
oracle_csi_nbr,
dba_pager_nbr
from host
where host_name = rtrim(host_name_in))
loop
htp.print('Host Name: ');
htp.formText('host_name',10,50,host_rec.host_name);
htp.print('Customer_name: ');
htp.formText('cust_name',10,50,host_rec.cust_name);
htp.nl;
htp.nl;
htp.nl;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
Note that the htp.formText function is used in Listing 9.12 to create the data input screen. Listing 9.13
displays the HTML source code generated from the code in Listing 9.12.
<HTML>
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
<HEAD>
<TITLE>s10</TITLE>
<H1>Oracle information database</H1>
<H1 ALIGN="C">Host Display</H1>
</HEAD>
<TD><A HREF="update_host?my_rowid=0000000F.0000.0005">
Update this host</A></TD>
<BR>
<BR>
Host Name:
<INPUT TYPE="text" NAME="host_name" SIZE="10" MAXLENGTH="50"
VALUE="">
IP address:
<INPUT TYPE="text" NAME="ip_address" SIZE="20" MAXLENGTH="50"
VALUE="">
Customer_name:
<INPUT TYPE="text" NAME="cust_name" SIZE="10" MAXLENGTH="50"
VALUE="">
Operating System:
<INPUT TYPE="text" NAME="os_type" SIZE="10" MAXLENGTH="50"
VALUE="Solaris">
Operating System version:
<INPUT TYPE="text" NAME="os_version" SIZE="10" MAXLENGTH="50"
VALUE="2.5">
Oracle CSI Number:
<INPUT TYPE="text" NAME="oracle_csi_nbr" SIZE="10" MAXLENGTH="50"
VALUE="1234567">
DBA pager number:
<INPUT TYPE="text" NAME="dba_pager_nbr" SIZE="10" MAXLENGTH="50"
VALUE="">
<BR>
<BR>
</FORM>
</BODY>
</HTML>
Listing 9.13 shows that htp.formText created <INPUT> tags. Figure 9.2 displays the Web page created from
the HTML code in Listing 9.13.
WebServer provides other methods for displaying row data. Another way to display the data is by using the htp.
tableData procedure, as shown in Listing 9.14.
Listing 9.14 Returning a single row into a Web page using htp.tableData.
create or replace
procedure formfield (p_label in varchar2,
p_name in varchar2,
p_value in varchar2) is
BEGIN
htp.tableRowOpen;
htp.tableData (p_label);
htp.tableData(htf.formHidden('p_name', p_name)||
htf.formText(p_value, 10, 50, cvalue => p_value));
htp.tableRowClose;
end;
create or replace
procedure update_form (host_name_in in varchar2) is
BEGIN
htp.formOpen('do_update');
for host_rec in (
select
rowid,
host_name,
ip_address,
cust_name,
os_type,
os_version,
oracle_csi_nbr,
dba_pager_nbr
from host
where host_name = rtrim(host_name_in))
loop
htp.tableData(htf.anchor('update_host?my_rowid='||host_rec.rowid,
'Update this host'));
htp.nl;
htp.nl;
htp.nl;
htp.nl;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
Listing 9.14 is a very important example—it shows the use of a subfunction called formfield that takes the
incoming data and nests three htp functions. The structure is as follows:
htp.tableData (htf.formHidden||htf.formText)
Note: Remember from Chapter 7 that functions called from within htp procedures use their htf
equivalent.
The formfield subfunction does more than simply display Oracle data on a Web page. The htp.tableData
function encapsulates the htf.formHidden and the htf.formText, while htp.formhidden stores the column
value into an array. Finally htp.formText is used to display the column value. Listing 9.15 is the HTML that
results from the WebServer code displayed in Listing 9.14.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
</TR>
Operating System version:
<TR>
<TD>os_version</TD>
<TD><INPUT TYPE="hidden" NAME="p_name" VALUE="p_os_version">
<INPUT TYPE="text" NAME="2.5" SIZE="10" MAXLENGTH="50" VALUE="2.5">
</TD>
</TR>
Oracle CSI Number:
<TR>
<TD>oracle_csi_nbr</TD>
<TD><INPUT TYPE="hidden" NAME="p_name" VALUE="p_csi_nbr">
<INPUT TYPE="text" NAME="1234567" SIZE="10" MAXLENGTH="50"
VALUE="1234567"></TD>
</TR>
DBA pager number:
<TR>
<TD>dba_pager_nbr</TD>
<TD><INPUT TYPE="hidden" NAME="p_name" VALUE="p_dba_pager_nbr">
<INPUT TYPE="text" NAME="777-7777" SIZE="10" MAXLENGTH="50"
VALUE="777-7777"></TD>
</TR>
<BR>
<BR>
</FORM>
</BODY>
</HTML>
Note that the executable HTML is not identical to the HTML generated in Listing 9.13. The use of htp.
tableData creates two <INPUT> tags: one for the hidden form values and another to display the input
values on the Web page.
Returning a list of values to Web pages using PL/SQL is a very simple matter, especially when compared
to returning a list of values into a SQL*Form. Unlike SQL*Forms, Web pages allow for an almost infinite
number of repeating values to be displayed on a single Web page. Because Web browsers enable the end
user to scroll through Web pages, a Web page with 500 rows can be displayed and the end user can simply
browse forward and backward through the Web page. This means that developers no longer have to deal
with the problem of paging screens and forcing the end user to manually retrieve the next set of repeating
data (see Listing 9.16).
Listing 9.16 Retrieving multiple rows from Oracle into a Web page.
create or replace
procedure s10(host_name_in in varchar2) as
responsibility varchar2(20);
dba_name varchar2(20);
dept_name varchar2(20);
phone_nbr varchar2(20);
e_mail varchar2(20);
office_hrs varchar2(20);
home_phone_nbr varchar2(20);
counter integer := 0;
cursor c2 is
select
responsibility,
a.dba_name,
dept_name,
phone_nbr,
e_mail,
office_hrs,
home_phone_nbr
from dba_host a, dba b
where host_name = rtrim(host_name_in)
and
a.dba_name = b.dba_name;
dba_rec c2%ROWTYPE;
BEGIN
htp.htmlOpen;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's10');
htp.headOpen;
htp.title('s10');
htp.header(1,'Oracle information database');
htp.header(1,'Host Display','C');
htp.headClose;
htp.header(2,'DBA name Responsibility phone e-mail
office_hrs home phone : ');
htp.nl;
open c2;
loop
counter := counter + 1;
fetch c2 into dba_rec;
EXIT WHEN c2%NOTFOUND;
htp.formText('dba_name'||counter,10,50,dba_rec.dba_name);
htp.formText('responsibility'||counter,10,50,dba_rec.responsibility);
htp.formText('dba_phone'||counter,10,50,dba_rec.phone_nbr);
htp.formText('dba_e_mail'||counter,30,50,dba_rec.e_mail);
htp.formText('dba_office_hrs'||counter,10,50,dba_rec.office_hrs);
htp.formText('home_phone_nbr'||counter,10,50,dba_rec.home_phone_nbr);
htp.nl;
htp.nl;
end loop;
close c2;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 9.17 shows another technique for retrieving multiple rows from Oracle to display on a Web page.
Listing 9.17 Retrieving multiple rows from Oracle into a Web page using a for loop.
create or replace
procedure formcheckbox (tab_name in varchar2) is
cursor cols is
select
column_name
from
dba_tab_columns
where
table_name = upper(tab_name);
BEGIN
. . . .
. . . .
end;
As you can see in Listings 9.16 and 9.17, a cursor is used to navigate through the Oracle database,
returning one row at a time. As we know, a single SQL statement may return hundreds of rows, and a
cursor is used to allow PL/SQL to process the rows sequentially. In the above example, htp.print is called
one time for each row returned from the cursor.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Whenever a request is made to an Oracle database, the application must become aware of the status
of the request after it has been received by Oracle. (See Figure 9.3.) In Oracle SQL, there are
several commonly received error statuses, and these need to be checked by your WebServer
application to ensure that your process logic is synchronized with the actual results from the Oracle
database. For example, you would not want to issue an sql update statement against a row that was
not successfully retrieved from Oracle.
In practice, there are only a few conditions that need to be checked from Oracle, but there may be
many unexpected return codes that also need to be checked. It is always a safe practice to perform
the following generic check whenever PL/SQL is run against the Oracle database.
You can define custom error codes according to the needs of your WebServer application. For
example, Listing 9.18 defines a custom error code that raises an exception condition if a certain
column retrieved from a table is null.
address_in varchar(20);
address_missing EXCEPTION;
BEGIN
select address into my_address
from
customer_table
where
rowid = my_rowid;
EXCEPTION
when no_data_found then
error_web_page(Customer);
when bad_field
error_web_page(Customer);
end;
In Listing 9.18, three conditions are raised: one if the rowid fails to retrieve a customer row,
another when the address column is NULL, and a third check for any other unexpected return
codes from Oracle. All of these conditions will invoke an error Web page that accepts the error
message and terminates processing.
When using a WebServer application, it is a good idea to create a Web page specifically for the
purpose of displaying unexpected Oracle return codes. While your end users should never see this
page, it can be an extremely useful tool for debugging your WebServer application. An error page
will also aid in the diagnosis of production problems after your WebServer application has been
completed. Listing 9.19 shows PL/SQL WebServer code used to generate a generic error page.
create or replace
procedure error_web_page (error_table in varchar2)
is
BEGIN
htp.htmlOpen;
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 'error_web_page');
htp.headOpen;
htp.title('error_web_page');
htp.header(1,'Oracle error display page');
htp.nl;
htp.nl;
htp.nl;
htp.bodyClose;
htp.htmlClose;
end;
Figure 9.4 is the Web page that displays when the code from Listing 9.19 is invoked from
WebServer.
Figure 9.4 A sample WebServer error page for unexpected return codes.
Any proficient PL/SQL programmer will be able to provide a complete listing of all the built-in
exception conditions of PL/SQL. For detailed information, see the PL/SQL User’s Guide and
Reference by Oracle Corporation.
Summary
Now that we’ve covered the basics of using PL/SQL with Oracle WebServer, we are ready to take
a close look at how complete applications are designed with WebServer. The following chapter
shows screen structures that can be used on a Web page, including radio buttons, pop-up menu
values, and checkboxes. Later, we’ll take a look at advanced WebServer application development
techniques.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select
CHAPTER 10
Managing WebServer Forms And Security
In general, the fundamental nature of online applications does not change simply because the front end
resides on a Web page. You still need to define menus, data input fields, pop-up lists, radio buttons,
checkboxes, and so on. This chapter assumes that you are familiar with these constructs and focuses on
how they are efficiently implemented using WebServer. In addition, general rules for mapping database
tables to WebServer applications are addressed, and a method for managing Oracle updates is described.
Database security is of primary importance when designing a front end that can be accessed from the
Internet. You should take special effort to ensure that unauthorized access is not made to your Oracle
database, and you should also take steps to ensure that system performance does not suffer when
communicating with the Oracle database. As you know, Web pages are static, and communications are
terminated with Oracle each time a Web page is sent to the end user. This chapter discusses how security
and access concurrency are managed within WebServer. WebServer forms must be designed so that
access concurrency is maintained while providing adequate protection for the Oracle information in your
database.
In general, a form on a WebServer application differs from a traditional online screen. Because a
WebServer page interacts with both Oracle data and end users, the WebServer page needs special objects
for communication, including data input fields, radio buttons, checkboxes, hypertext links, and push
buttons. These objects constitute the interface to the WebServer page and enable communication between
the Oracle database and the user of the Web page.
Data input fields are displayed on a Web page as empty text boxes. Data input fields can be displayed
within Oracle WebServer with either default values or values retrieved from the Oracle database.
Developers can control the width of text boxes and the number of characters contained in them, but they
cannot control the height of the boxes. Figure 10.1 shows a data input field for a Web page.
NOTE: A data input area is defined using the htp.formText call, but you may also want to use
htp.formHidden to store the form values for passing them to an update routine. For a detailed
description of the use of these procedures, see Chapter 7, WebServer’s HTP Utilities.
Multiple occurrences of input fields are commonly found when a one-to-many data relationship is
displayed on a Web page. For example, a customer page may have repeating groups for each order placed
by a customer. Because each customer may place many orders, this one-to-many database relationship
will be represented on the Web page as a list of repeating values.
There is one significant difference between a Web page list and the type of repeating list that an
SQL*Forms user may be accustomed to defining. In a traditional display mode, the application is
required to display the data in an 80-character wide by 23-character high display screen, but a Web page
has no such constraints. Consequently, where a traditional application would force the end user to press a
button marked More to see the next series of values, the Web page expands to the length necessary to
display all of the information. This feature of Web pages greatly simplifies the presentation of
information.
To illustrate, let’s consider the situation where a WebServer application manages environmental
information about a Unix server. When the user of the WebServer application enters a server name, a
Web page is displayed that shows basic server information, including a list of all the DBAs who support
the Oracle databases on that server. (See Figure 10.2.)
But how was the screen in Figure 10.2 created? Listing 10.1 shows the PL/SQL that was invoked to
create the Web page shown in Figure 10.2.
create or replace
procedure s10(host_name_in in varchar2) as
responsibility varchar2(20);
dba_name varchar2(20);
dept_name varchar2(20);
phone_nbr varchar2(20);
e_mail varchar2(20);
office_hrs varchar2(20);
home_phone_nbr varchar2(20);
counter integer := 0;
cursor c2 is
select
responsibility,
a.dba_name,
dept_name,
phone_nbr,
e_mail,
office_hrs,
home_phone_nbr
from dba_host a, dba b
where host_name = rtrim(host_name_in)
and
a.dba_name = b.dba_name;
dba_rec c2%ROWTYPE;
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.title('s10');
htp.bodyOpen;
htp.FormOpen(owa_util.get_owa_service_path || 's10');
htp.header(1,'DBA Display','C');
htp.headClose;
htp.nl;
open c2;
loop
counter := counter + 1;
fetch c2 into dba_rec;
EXIT WHEN c2%NOTFOUND;
htp.formText('dba_name'||counter,10,50,dba_rec.dba_name);
htp.formText('responsibility'||counter,10,50,dba_rec.responsibility);
htp.formText('dba_phone'||counter,10,50,dba_rec.phone_nbr);
htp.formText('dba_e_mail'||counter,30,50,dba_rec.e_mail);
htp.formText('dba_office_hrs'||counter,10,50,dba_rec.office_hrs);
htp.formText('home_phone_nbr'||counter,10,50,dba_rec.home_phone_nbr);
htp.nl;
htp.nl;
end loop;
close c2;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
Notice how the repeating groups are mapped out to the Web page. The cursor c1 is defined for the select
that will return only a single row, while cursor c2 is defined for the query that will return multiple rows.
The code then steps into a loop, repeating the htp.formText calls to display each row of information.
This loop continues until there are no more rows fetched from Oracle, as indicated by the EXIT WHEN
c2%NOTFOUND statement. In this example, the loop executed three times, once for each DBA
assigned to work on this server.
Of course, the HTML document generated from this loop will not have any indication that a loop was
involved in creating the HTML document. Listing 10.2 shows the HTML document generated from the
PL/SQL shown in Listing 10.1. Notice that the repeating groups of DBA information use numbers in the
data names to uniquely distinguish each field.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
<HTML>
<HEAD>
<TITLE>s10</TITLE>
<H1>Oracle information database</H1>
<H1 ALIGN="C">Host Display</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
<INPUT TYPE="submit" NAME="s10uh" VALUE="Update Host Information">
<BR>
<BR>
Host Name:
<INPUT TYPE="text" NAME="host_name" SIZE="10" MAXLENGTH="50"
VALUE="jacob">
IP address:
<INPUT TYPE="text" NAME="ip_address" SIZE="20" MAXLENGTH="50"
VALUE="134.221.90.xx">
Customer_name:
<INPUT TYPE="text" NAME="cust_name" SIZE="10" MAXLENGTH="50"
VALUE="STAN">
Operating System:
<INPUT TYPE="text" NAME="os_type" SIZE="10" MAXLENGTH="50"
VALUE="Solaris">
Operating System version:
<INPUT TYPE="text" NAME="os_version" SIZE="10" MAXLENGTH="50"
VALUE="2.5">
Oracle CSI Number:
<INPUT TYPE="text" NAME="oracle_csi_nbr" SIZE="10" MAXLENGTH="50"
VALUE="1234567">
DBA pager number:
Checkboxes
As you probably already know, checkboxes are used when you need to display items where more than
one item can be selected. In other words, checkboxes may be used in a WebServer form whenever the
phrase “check all that applies” is appropriate.
NOTE: Checkboxes are defined using the htp.formCheckbox call. For a detailed description of
the use of this procedure, see Chapter 7, WebServer’s HTP Utilities.
In the example shown in Figure 10.3, you can see a page where a Web user can choose the columns that
they would like to display from a table.
Notice that in the example shown in Figure 10.3, the values next to each checkbox comes from the
dba_tables view inside the Oracle dictionary. The ability of WebServer to query databases and display
the results in a checkbox is a very powerful feature.
Radio Buttons
Radio buttons are used when mutually exclusive items, such as sex, race, nationality, must be chosen.
Unlike checkboxes, radio buttons do not allow multiple items to be selected at one time—radio buttons
are reserved for “one-or-the-other” type responses. Whenever a radio button is selected, the previously
selected radio button is automatically deselected to ensure that only one value is indicated. Figure 10.4
shows a WebServer screen using radio buttons.
NOTE: In the example shown in Figure 10.4, the values next to each radio button have been
retrieved from an Oracle table. Radio buttons are defined using the htp.formRadio call. For a
detailed description of the use of this procedure, see Chapter 7, WebServer’s HTP Utilities.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Pop-up lists are very useful within WebServer applications and are used to limit the
type of information provided by end users, as well as to spare end users from having to
manually type in information. Using Oracle WebServer, it is very easy to get values
for pop-up lists from Oracle tables, but care needs to be taken not to create excessive
processing overhead when retrieving pop-up values. For example, it might be tempting
to issue the SQL select distinct customer_type from CUSTOMER while ignoring
the fact that the CUSTOMER table may contain millions of rows. While the select
distinct technique ensures that only valid values are presented to the Web user, a
better technique is to create a temporary Oracle table with the unique values and then
refresh this temporary table on a periodic basis. For example, a shell script1 called
make_list.sh could be executed once each week to refresh the table values. Listing
10.3 shows how a shell script called make_list.sh might appear.
To ensure that this table is refreshed each week, the following entry could be made
into the Unix crontab. A crontab is Unix jargon for chronological table, which is a list
of entries in a file that specifies programs and the exact times that each program will
be run. In the following example, the program called make_list in the /oracle/sql
directory is executed at noon on Sunday:
00 12 * * 0 /oracle/sql/make_list.sh 2>&1
When a list of distinct table values resides in an Oracle table, the data can be easily
gathered from the table using a cursor. Listing 10.4 shows how a table called HOST is
queried to supply the values for the pop-up list.
create or replace
procedure s00 as
host_name_in varchar2(20);
cursor c1 is
select
host_name
from HOST
order by host_name;
host_rec c1%ROWTYPE;
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.title('s00');
htp.preOpen;
htp.header(1,' Oracle Information Database');
htp.header(1,' Main Menu','C');
htp.preClose;
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 's10');
htp.nl;
htp.nl;
htp.formHidden('host_name_in', host_name_in);
htp.formSelectOption(host_rec.host_name);
end loop;
close c1;
htp.formSelectClose;
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Listing 10.5 displays the HTML document created from the Oracle stored procedure
shown in Listing 10.4.
Listing 10.5 The HTML generated for a pop-up list with WebServer.
<HTML>
<HEAD>
<TITLE>s00</TITLE>
<PRE>
<H1>Oracle Information Database</H1>
<H1 ALIGN="C">Main Menu</H1>
</PRE>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
<BR>
<BR>
<INPUT TYPE="hidden" NAME="host_name_in" VALUE="">
Choose the Host:<SELECT NAME="host_name_in">
<OPTION>bobby
<OPTION>jung
<OPTION>sandbox
<OPTION>skinner
<OPTION>walden
<OPTION>zonker
</SELECT>
<BR>
<BR>
</FORM>
</BODY>
</HTML>
Figure 10.5 displays the Web page created from the HTML source code shown in
Listing 10.5.
Menu Screens
With Oracle WebServer, there are many tools that you can use to provide menu
choices to end users. Whereas character-based application systems of the 1980s only
allowed function keys for transferring between screens, WebServer provides a variety
of methods for interscreen travel, including:
As with other GUI application systems, designers need to be careful when choosing
end-user options available in WebServer, because it is easy to create overly
complicated or badly designed menu screens. Care should be taken to clearly choose
the methods used to guide your end users through your application structure. Today’s
state-of-the-art menus utilize image maps, whereby a large image (a GIF or JPEG file)
is displayed. This image contains the main menu for the application. End users click
on areas of the image to indicate to WebServer what information they would like to
view. To illustrate this principle, consider the home page for Oracle Magazine, shown
in Figure 10.6.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserv
Click Here!
Click Here!
ITKnowledge
Please Select
Updating The Oracle Database From A Web Page
Updating an Oracle database from a Web page is similar to the procedure for updating
Oracle data from SQL*Forms. However, there are some unique OWA packages that
Oracle provides to assist in this function (see Figure 10.7). In general, the following
steps occur when updating an Oracle database from a Web page:
• Reinvokes the original Web page, passing a status message for display
on the invoking Web page.
NOTE: WebServer can not issue any long-term row locks against the Oracle
database. (See Chapter 11, WebServer Navigation And Concurrency
Management.) Therefore, because a subsequent retrieval of the row by another
task may have changed the column contents, it is imperative that your
WebServer code checks to see if any columns have been updated since your
Web page mapped out to the end user. There are several techniques for doing
this, all of which involve checking the original row contents against the
current row values before updating the row.
Chapter 9 discussed two ways that row information can be passed to an update
procedure. In order to update Oracle, you need two things: the rowid and a list of the
values to be changed. The update procedure can be invoked by using htp.formSubmit
(a push button) or htp.anchor (a hyperlink). In either case, you must pass the required
information to the update procedure. Following are the steps for updating Oracle from
a Web page:
2. Store the rowid and column values using htp.formHidden, and then
transfer to the update routine using htp.formSubmit.
3. When the update routine takes control, it will update the row using the
rowid, getting the values for the columns using owa_parms.get.
As you know, once name-value pairs are saved into an array with htp.formHidden,
they can be passed to another procedure where the pairs can be interrogated and used
to update the Oracle database. Listing 10.6 shows the WebServer process of receiving
a rowid and name-value pairs and updating the HOST table.
procedure update_customer (
p_rowid in rowid,
p_name in owa_parms.array,
p_values in owa_parms.array)
is
BEGIN
owa_parms.register (p_name, p_values);
os_type = owa_parms.get('p_os_type'),
os_version = owa_parms.get('p_os_version'),
oracle_csi_nbr = owa_parms.get('p_oracle_csi_nbr'),
dba_pager_nbr = owa_parms.get('p_dba_pager_nbr')
where rowid = p_rowid;
...
...
end;
In Listing 10.6, you can see that each column of the desired row is set equal to
owa_parms.get(‘name_value’). The owa_parms.get function accepts the name of an
array item and returns the value associated with the name when the htp.formHidden
statement is used. To thoroughly understand how the owa_parms package works, you
should look at the source code for the package in the $ORACLE_HOME/ows2/admin
di rectory.
Use of this site is subject to certain Terms & Conditions, <a href="../../../../copyright.h
Click Here!
Click Here!
ITKnowledge
The processing of updating multiple rows from a WebServer page is not trivial. Unlike other
tools—such as SQL*Forms—where repeating items can be declared as an array and referenced by it’s
subscript, Web pages do not allow the concept of arrays or repeating groups. When repeating rows are
mapped to a Web page, they must be given unique names so that they can be referenced by subsequent
routines. Listing 10.7 shows how repeating data rows can be given unique names by using a counter.
create or replace
procedure s10(host_name_in in varchar2) as
responsibility varchar2(20);
dba_name varchar2(20);
dept_name varchar2(20);
phone_nbr varchar2(20);
e_mail varchar2(20);
office_hrs varchar2(20);
home_phone_nbr varchar2(20);
counter integer := 0;
cursor c2 is
select
responsibility,
a.dba_name,
dept_name,
phone_nbr,
e_mail,
office_hrs,
home_phone_nbr
from dba_host a, dba b
dba_rec c2%ROWTYPE;
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.title('s10');
htp.header(1,'DBA Display','C');
htp.headClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 's10');
htp.formSubmit('s10ud','Update DBA Information');
htp.nl;
htp.nl;
open c2;
loop
counter := counter + 1;
fetch c2 into dba_rec;
EXIT WHEN c2%NOTFOUND;
htp.formText('dba_name'||counter,10,50,dba_rec.dba_name);
htp.formText('responsibility'||counter,10,50,dba_rec.responsibility);
htp.formText('dba_phone'||counter,10,50,dba_rec.phone_nbr);
htp.formText('dba_e_mail'||counter,30,50,dba_rec.e_mail);
htp.formText('dba_office_hrs'||counter,10,50,dba_rec.office_hrs);
htp.formText('home_phone_nbr'||counter,10,50,dba_rec.home_phone_nbr);
htp.nl;
htp.nl;
end loop;
close c2;
htp.formClose;
htp.bodyClose;
htp.htmlClose;
end;
From Listing 10.7, you can see that as each row is retrieved from the DBA_HOST table, a variable
called counter is incremented and then concatenated onto the name of the form field (in htp.
formText). Listing 10.8 shows the HTML generated for this page.
<HTML>
<HEAD>
<TITLE>s10</TITLE>
<BR>
<H1 ALIGN="C">DBA Display</H1>
</HEAD>
<BODY>
<FORM ACTION="/ows-bin/owa/s10" METHOD="POST">
<INPUT TYPE="submit" NAME="s10ud" VALUE="Update DBA Information">
<BR>
<BR>
<H2>DBA name Responsibility phone e-mail office_hrs
home phone : </H2>
<BR>
<INPUT TYPE="text" NAME="dba_name1" SIZE="10" MAXLENGTH="50"
VALUE="burleson">
<INPUT TYPE="text" NAME="responsibility1" SIZE="10" MAXLENGTH="50"
VALUE="PRIMARY">
<INPUT TYPE="text" NAME="dba_phone1" SIZE="10" MAXLENGTH="50"
VALUE="777-7777">
<INPUT TYPE="text" NAME="dba_e_mail1" SIZE="30" MAXLENGTH="50"
VALUE="l888888@ravingo">
<INPUT TYPE="text" NAME="dba_office_hrs1" SIZE="10" MAXLENGTH="50"
VALUE="m-f 7-4">
<INPUT TYPE="text" NAME="home_phone_nbr1" SIZE="10" MAXLENGTH="50"
VALUE="223-1836">
<BR>
<BR>
<INPUT TYPE="text" NAME="dba_name2" SIZE="10" MAXLENGTH="50"
VALUE="papaj">
<INPUT TYPE="text" NAME="responsibility2" SIZE="10" MAXLENGTH="50"
VALUE="BACKUP">
<INPUT TYPE="text" NAME="dba_phone2" SIZE="10" MAXLENGTH="50"
VALUE="777-4444">
<INPUT TYPE="text" NAME="dba_e_mail2" SIZE="30" MAXLENGTH="50"
VALUE="winner@roch">
<INPUT TYPE="text" NAME="dba_office_hrs2" SIZE="10" MAXLENGTH="50"
VALUE="m-f 9-4">
<INPUT TYPE="text" NAME="home_phone_nbr2" SIZE="10" MAXLENGTH="50"
VALUE="443-4446">
<BR>
<BR>
<INPUT TYPE="text" NAME="dba_name3" SIZE="10" MAXLENGTH="50"
VALUE="rivera">
<INPUT TYPE="text" NAME="responsibility3" SIZE="10" MAXLENGTH="50"
VALUE="OTHER">
<INPUT TYPE="text" NAME="dba_phone3" SIZE="10" MAXLENGTH="50"
VALUE="551-5554">
<INPUT TYPE="text" NAME="dba_e_mail3" SIZE="30" MAXLENGTH="50"
VALUE="5555555@cheo">
<INPUT TYPE="text" NAME="dba_office_hrs3" SIZE="10" MAXLENGTH="50"
VALUE="m-f 5-4">
<INPUT TYPE="text" NAME="home_phone_nbr3" SIZE="10" MAXLENGTH="50"
VALUE="555-5536">
<BR>
<BR>
</FORM>
</BODY>
</HTML>
Three rows were retrieved by cursor c2, and you can see a series of unique data names, dba_name1,
dba_name2, and dba_name3. Now that uniquely defined form field names have been created, the
information can be passed to ftp.formHidden, in exactly the same fashion as passing a single row.
Then, each row will be updated by retrieving the column values using owa_parms.get.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Security And WebServer Forms
For many database administrators, the terms open systems and security are oxymorons
since it is often impossible to have open systems while maintaining adequate security.
Maintaining security for a centralized system is difficult enough, and when faced with
a network of networked databases, maintaining access and update security is a
formidable challenge. In practice, security is an afterthought. In fact, its commonplace
to see a lack of up-front planning for systemwide security, especially for distributed
databases created as a result of external factors, such as corporate acquisitions.
Oracle claims that WebServer is the first Web server to support full end-to-end
security. By end-to-end, Oracle means that the WebServer maintains security at the
database, server (via a firewall), and client levels, all while maintaining acceptable
levels of performance.
Let’s examine the security checks that take place when a PL/SQL request is made to
the Oracle WebServer. Unlike an ordinary Web page where an HTML document is
requested from a Unix flat file, Oracle provides far more security than the security
permissions Unix maintains against HTML documents. With Oracle WebServer, the
first level of authentication occurs when the PL/SQL agent connects to the Oracle
server. In the WebServer configuration, only the predefined user may establish
WebServer connections, thereby preventing anyone other than the PL/SQL agent from
using the Web-Server mechanism to connect to an Oracle database. Once connected,
the PL/SQL agent must identify itself to Oracle, using an Oracle username. The
username is the key to Oracle’s security setup. The proper Oracle username grants
users the authority to load and execute stored procedures, enabling requested data to
be gathered from the Oracle database. As a stored procedure is executed, the end user,
using the proper password, gains the same access privileges as the owner of the stored
procedure.
Within Oracle, two methods are used to enforce security. The first (and most popular)
method is the use of Oracle roles, whereby when a role is created, it is granted table
and system privileges, and then is assigned to Oracle users. The second approach is the
grant execute statement. With grant execute, privileges on a specific package or
stored procedure are granted to users. When users execute the stored procedure, they
automatically get the same privileges as the owner or creator of the stored procedure.
It should be obvious that these two methods for managing Oracle security do not
complement one another. The combined use of grant execute statements and role-
based security will eventually lead to a situation where it is impossible to determine
the privileges of a user in an Oracle database. To understand how the “grant execute”
method be implemented for WebServer, let’s take an in-depth look at Oracle security
and how it can be applied to WebServer applications.
Oracle Security
Oracle database security is applied with the SQL grant statement and removed with
the revoke statement. While these two basic commands appear trivial, there are
hundreds of different types of access privileges that can be granted and revoked. There
are two categories of privileges that can be granted: table privileges (e.g., grant select
on customer_table to Fred;), where a specific operation against a specific table is
granted to a specific user, and system privileges (e.g., grant select any table to
Fred;), whereby a range of privileges are granted to a specific user.
In Oracle, access to tables is controlled with grant statements. Because grants are
assigned for eac h SQL operation (select, update, insert, and delete) on each
individual table, and because an application may consist of hundreds of tables, finding
a way to group tables into functional categories can greatly simplify security
administration. For example, some distributed Oracle databases have large replicated
applications where each application may have hundreds of tables. For example,
consider an income tax processing application that has a cloned database for each of
the 50 states. When hundreds of tables are multiplied by 50 horizontal partitions, there
are many thousands of distinct tables that must be granted to the end users. Clearly,
maintaining grants on thousands of distinct tables would be a messy chore. The goal of
WebServer security is to protect against the willful or accidental corruption of data,
and to ensure that sensitive operations are controlled without being cumbersome for
the DBAs or obtrusive to the end user. The solution to the maintenance of large
numbers of tables is Oracle’s role-based security. As with all vendors, the Oracle
implementation of role-based security is neither simple nor intuitive, and this section
will discuss the major issues involved in establishing a role-based Oracle environment.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
Oracle Privileges
There are two classifications of grant commands: system privileges and object
privileges. The difference is primarily one of scope; an object privilege is granted to a
specific database object such as a customer table, while a system privilege applies to
all instances of an object type.
System Privileges
System privileges are the right to perform an action, or perform an action on all
instances of a particular object type (e.g., grant select any table to jenny_burleson;).
There are dozens of system privileges that can be used to regulate access to all
functions within the database. System privileges are expressed in three parts: action,
global (any), and object_type. Based on this taxonomy, system privileges are
expressed with actions and the object types associated with actions:
Action
• create
• drop
• alter
• grant
• select
• audit (any)
• manage (tablespace)
• backup (table)
• force (transaction)
• become (user)
Object Type
• cluster
• procedure
• database
• database link
• privilege
• profile
• role
• session
• sequence
• snapshot
• system
• synonym
• table
• tablespace
• trigger
• user
Object Privileges
Object privileges are the rights to perform an action on a specific, named object (e.g.,
grant update on cat.food to sarah_tytler;).
Object privileges are usually expressed in the form action-object-objectname and are
delineated in Table 10.1.
You can combine certain object privileges with objects. Therefore, the following
object privileges are valid examples:
One of the most important features for WebServer security is the ability to enforce
access to a table by using functions, stored procedures, and packages. A function is a
code snippet that can contain SQL that accepts input variables and returns values to
the caller of the function. A stored procedure is a piece of code that has embedded
SQL commands within its body. A package is a collection of Oracle stored procedures
and/or Oracle functions that logically bundles the stored procedures together into a
single unit. For example, the following Oracle package, called human_resources,
contains the functions and stored procedures that are required to perform HR tasks:
procedure hire_employee
begin ... end;
function give_raise
begin ... end;
procedure manage_adjunct
begin ... end;
The confounding problem with procedures and packages is that their security is
managed in an entirely different fashion from other grant statements. When a
WebServer developer role is given execute privileges on a package, the user executing
the package will be operating under the security domain of the owner of the procedure,
and not their own defined security domain. In other words, a user who does not have
privileges to update employee rows can get this privilege by being authorized to
execute a procedure that updates employees. From the DBA’s perspective, a database
security audit would not reveal this update capability.
The Oracle documentation describes the operation of stored procedure security and
how it differs from role-based security. The application developer’s guide states that
“the owner (of a stored procedure) cannot have obtained required privileges through
roles.” It also follows that someone cannot grant execute on a stored procedure to a
role. execute must be explicitly granted to a user—bypassing all roles. While this may
sound like a bug, Oracle calls it a “design issue.” However, there is an enhancement
request asking for this process to be changed (Oracle enhancement request #168358).
This issue is also covered in Oracle bulletin #105025.435 Role Restrictions, with an
explanation of why this restrictio1n exists.
The same security principle applies to using Oracle triggers. For example, a user
cannot create a trigger based on privileges that they received by being granted a role.
Following the same rule, a user cannot create an Oracle stored procedure based on
privileges that they received through being granted a role. The exclusive grant to the
users works because the grant is not coming from a role.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
As mentioned earlier in this chapter, privileges are granted or revoked at the individual user level.
Because all privileges and users are specified at the most atomic level, a database with 10 tables and
100 users would require 4,000 specific grant statements. Fortunately, Oracle SQL provides a method
for categorizing privileges and users, making security more manageable.
Object privileges can be combined into a single grant statement. For example, when a table is created,
access to the table is limited to the creator of the table. If user CAT creates a table called FOOD, then
access to the table could be granted to all users with the statement:
One confounding feature of Oracle SQL is the cascading ability of grant privileges. If USER1 has
been given a privilege with the grant option, that user now has the ability to grant their privileges to
any other user. For example, if the DBA issues the statement grant all on MY_TABLE to
sarah_tytler with grant option, sarah_tytler may now distribute this privilege to andy_burleson by
stating grant all on MY_TABLE to andy_burleson with grant option. To further confound matters,
andy_burleson may now, in turn, give this privilege to other users, and so on, ad infinitum.
Fortunately, the grant option clause in Oracle does not work with roles. Therefore, the following
statement would not be permitted in Oracle:
Cascading Revokes
Cascading revokes only apply to non-DDL system privileges and object privileges. For example,
consider the following sequence of commands:
In this scenario, USER2 continues to have create table privileges even though the create table
privilege has been revoked from the user who granted the privilege to USER2. The moral is: Don’t
use the admin option. In all other cases (except system DDL privileges), the initial revoke will
cascade to all who have been granted the privilege. A good example is a table owner, who grants
select privileges to USER1 with grant option, and then USER1 grants select to all of his friends.
When the table owner revokes the select privilege from USER1, all users who received their grant
from USER1 will also lose their privileges. A more extreme example would be when the DBA allows
anyone to select from a table (grant select any table to public), and then revokes the privilege
(revoke select any table from public). Any select references to any tables in the entire database will
fail, unless other object privileges have been used to grant access.
grant Statements
When using grant statements, there is a method to negate all security for a specific object. Security
can be explicitly turned off for an object by using public as the receiver of the grant. For example, to
turn off all security for MY_TABLE, you could enter:
Security is now effectively turned off for MY_TABLE, and restrictions may not be added with the
revoke command. For example, if USER1 and USER2 are not allowed to delete rows from
MY_TABLE, you could not enter revoke delete on MY_TABLE to USER1. The public parameter
cannot be negated with revoke statements.
Roles
In Oracle, roles may be assigned to sessions, as well as individual users. For example, assume that you
want a user to have the role of customer_clerk, but only when the user is within the control of the
customer service application. When the user invokes the main menu for the customer service
application, the application could disable all previous roles for this user and force them into the
customer_service role as follows:
Note that the set role command cannot authorize users for roles that they have not been granted
privileges to use. Therefore, you must first grant the customer_service role to each end user.
For some WebServer applications, you may need to restrict access to certain columns within a table,
or even to certain rows within a table. By using roles with relational views, it is possible to restrict
select access to individual rows and columns within an Oracle table. For example, assume that a
PERSON table contains confidential columns, such as salary. Also assume that this table contains a
type column with the values exempt, non_exempt, and manager. Let’s say you want your end users
to have access to the PERSON table, but you wish to restrict access to the salary column and the
manager row. A relational view could be created to isolate the allowed columns and rows, as follows:
You could now grant access to this view to any Oracle user;
Oracle also allows grant statements to specify individual table columns, but column-level security can
only be used with update, insert, and references grants. Columns can be specified in the grant
statement with the columns enclosed in parentheses, as follows:
If you wish to change the grant to specify only the salary column, Oracle requires that all privileges
be revoked, and the individual columns readded. For example, the following code would revoke
update privileges for the salary column:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
In Oracle, synonyms are used to assign nicknames to tables. Synonyms are most commonly used
within Oracle to avoid having to qualify each table name with the name of the user who created
the table (e.g., create public synonym customer for MARIA_HESS.customer;). In a
distributed Oracle environment, synonyms are often granted to tables in order to avoid the use of
the location qualifier in the table name. For example, the Oracle statement
requires the developer to know that the EMPLOYEE table is located in London (where
@london is the TNS service name for Oracle SQL*Net). Synonyms are also commonly used to
hide the table owner name so that the SQL does not have to specify the table owner. For example:
allows the table to be referred to as CUSTOMER without any reference to the table owner of the
TNS location of the table.
A grant to a table automatically allows access to a table by its synonym, and also allows grants to
be specified for a table according to the synonym. In the following example, the user MYUSER is
granted access to the synonym emp for access to the table CAT.EMP. This grant will remain in
effect even if the synonym emp is dropped:
Session-Level Security
Session-level security can be enforced within WebServer, as well as within the Oracle database.
For example, a user may have update authority when accessing the customer data through the
WebServer application, but the authority should be rescinded if the user attempts to update
customers within SQL*Plus. To allow this, Oracle provides the
PRODUCT_ROLE_MANAGER_PROFILE table to enforce tool-level security, and the user
may be disabled from updating in SQL*Plus by making an entry into this table. For example, to
disable updates for user FLORENCE_FOOS, the DBA could state:
insert into
PRODUCT_ROLE_MANAGER_PROFILE
(product, userid, attribute, char_value)
values ("SQL*Plus", "FLORENCE_FOOS", "update", "disabled");
The user named FLORENCE_FOOS could still perform updates within the application, but
would be prohibited from updating while in the SQL*Plus tool. At this time, the following values
for the attribute column are being used:
• begin
• copy
• declare
• delete
• edit
• host
• insert
• update
In Oracle, you can disable unwanted commands for end users by using a wildcard in the attribute
column of the PRODUCT_PROFILE table. For example, to disable the delete command for all
users of SQL*Plus, you could enter:
insert into
PRODUCT_ROLE_MANAGER_PROFILE
(product, userid, attribute, char_value)
values ("SQL*Plus", "%", "delete", "disabled");
Unfortunately, while this is great for excluding all users, you cannot alter the tables to allow the
DBA staff to have delete authority. The only acceptable value for the char_value column is
disabled.
When an Oracle connection is made to a remote database, the security in the remote database will
be applied to the transaction, regardless of the security on the WebServer database. In other
words, the security is regulated at the remote destination, and the privileges at the WebServer
database are irrelevant. For example, assume that USER1 has grant select any table to USER1;
on database1 privileges. If USER1 attaches to a remote database, say database2, his grant has no
authority on tables that reside in database2. For distributed Oracle queries, the user must have
proper privileges on both of the databases involved in the update. For example, a user in London
may join two tables from New York and California, as follows:
At the time of the select, the user must have select privileges against both of the customer tables
or the entire transaction will fail.
As previously discussed, the recommended security option for WebServer is to assign roles to key
developers who create the PL/SQL stored procedures for WebServer. At the highest level, role
implementation for WebServer applications entails the following steps:
For existing systems, a new role-based security plan will replace all table-level grants with role-
level grants. All roles will be defined at the table-owner level (e.g., SALES, ADJUNCT), and
these roles will be combined so that all existing security is duplicated.
The existing table-level security will be cleaned up and replaced with roles. This approach will
take every existing application one at a time and perform the following steps. (We’ll assume that
the existing security is adequate for the protection of confidential information, and that any holes
in the SQL security are taken care of within the application code.)
1. Investigate the current security mechanism. Look at the grants for all of the tables,
cross-referencing the grants with the users. For tables with grants to public, all systems
users will be granted access. Check for and remove all grant options and with admin
options. Now, use a script to check the existing grant security for each database.
2. Create a role (or roles) to match each functional category of the WebServer application.
3. Grant access to the roles for each user, based on the table-level grants from Step 1. A
script exists (role.sql) to create the SQL syntax for converting table-based grants to role-
based security.
4. Drop all direct grants to tables, with the exception of the role grants. Notify the end
users, and carefully watch for security problems.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Creating Key Developer Roles
A few simple guidelines should be followed when determining the proper roles to assign to the WebServer
developers who will create the stored procedures. Remember, roles will be used by key developers when
they create PL/SQL stored procedures, and the privileges maintained by the key developers should be the
same as those required to execute the stored procedure.
In addition, using Oracle views may simplify security maintenance. In Oracle, a view is a “logical” table that
is comprised of numerous tables. For example, consider the following view definition:
select customer_name,
order_number,
order_date,
item_number,
quantity_ordered,
item_description,
item_cost
from
customer,
order,
line_item,
item
where
customer.customer_name = order.customer_name
and
order.order_number = line_item.order_number
and
line_item.item_number = item.item_number;
Now that this view has been created, it can be referenced as if it were a single, logical table. For example,
the following query will hide all of the complexity involved in the Oracle database retrieval:
In summary, the guidelines for effective role development include the following:
Because SQL security for applications is currently controlled at the table level, and an application may
consist of hundreds of tables, finding a way to group tables into functional categories can greatly simplify
administration. Functional security can be implemented using either role-based or procedure-based
categorization. For existing systems, role-based security can be implemented without disturbing existing
applications.
With WebServer-based development, roles are created for each developer, but be aware that special, read-
only roles may be created for linking between remote Oracle databases.
NOTE: When a view spans table-owners, all tables from a foreign owner (i.e., other than the owner
of the view), must be granted to the view-owner with grant option. Then, the view-owner can grant
the view to roles, because he is now allowed to grant access for the specific foreign-owner tables.
Each key developer role should consist of the table privileges required to perform application development
in the particular area. For example, a developer can not have drop any table privileges, because they would
have the ability to drop tables belonging to other applications. Therefore, the developer roles should be tied
to the role of the table-owner for their application. For example, the table-owner adjunct would own full
privileges on all objects created by adjunct, but could not drop tables belonging to sales. To create a
developer role for adjunct, the following SQL could be issued to allow full access to any objects within the
specified schema with:
Within their schema, developers require full system privileges on schema objects, including clusters, tables,
indexes, sequences, synonyms, tablespaces, triggers, and views. In addition, system privileges must be
assigned to the developers. System privileges include unlimited tablespace, connect, and resource. A
sample grant statement might appear as follows:
Each area within the WebServer application would get its own role assignment, which would encompass all
of the valid authorities needed by the end users. These roles would be similar to the authority of the table-
owner, but, instead of granting adjunct to public, the tables would be granted to the role associated with the
application. Note that roles, just like users, may be assigned passwords. For example:
For WebServer applications that access remote databases, select-only versions of the role could be
associated with the user ID that associates with the link. If a user requires access to more than one table-
owner, the roles could be combined, as follows:
At this point, you could specify ADJDB_LINK on any target system that requires a database link:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Once the appropriate roles have been identified and the privileges have been determined, a
plan must be devised to replace existing table-level security. Replacing table-level security
must be done unobtrusively. Ideally, end users and developers should not be aware that a
change has occurred. Replacing table-based security with role-based security includes the
following steps:
3. Assign all table-level grants to a new role. The following statement creates two
roles and then assigns the new roles to Oracle users:
4. Interrogate all end users to get their existing grants (if any). The following code
lists all Oracle users whose user ID begins with ‘OPS$’ who have been granted table-
level privileges:
5. Create and assign roles to all appropriate users. The following code creates a role
and assigns the role to a user:
6. Revoke existing grants (except the role) from users. The following code revokes
specific table-level privileges from a named user:
7. Wait one week. If there are no reported problems, revoke all grants to tables
(except the role). The following code revokes specific grants from public access:
8. Locate all other databases that access the database, and alter the links to specify
the read-only user ID instead of a table-owner ID. The following code ensures that a
database link uses a specific user ID when connecting to the remote database:
For WebServer applications that have successive degrees of refinement, you may want to
consider organizing roles in a hierarchy—assigning developers roles according to their
individual needs. For example, some key developers might write read-only queries against a
set of Oracle tables, while other developers might create the stored procedures that actually
update this set of tables. New roles can be created from existing roles, system privileges,
object privileges, or any combination therein, as shown in Figure 10.8.
Application-specific security can give much tighter control over security than data-specific
security. The DBA can authorize application owners to have the proper privileges to perform
their functions, without granting end users any explicit grants against the database. Instead,
end users are granted execute on the procedure, and the only way end users will be able to
access the data is through the procedure (e.g., grant execute on human_resources to
JONES;).
For specific applications, the user ID that serves as the table owner (e.g., custowner.
customer) can be used as the creator of the procedures. Table owners automatically receive
all authority against the tables they create, so no DBA intervention is necessary. Because the
procedures govern what the end user can and cannot perform, the only administration
required would be to bundle the procedures into a package and grant execute privileges to
the appropriate end users. There is no need to create huge grant scripts for each and every
end user, and there is no possibility of end users doing an end-run and accessing the tables
from within other packages.
Of course, this would require coordination with the application programmers, so that all SQL
is encapsulated into functions and procedures. Any SQL inserted directly into the application
code will fail at runtime. The PROCESS of consciously encapsulating code into functions
and procedures is beneficial for a number of reasons, including:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
An SQL script can create role-based security privileges, as shown in Listing 10.9. Once an existing schema
table owner has been located, the following script can be used to generate all of the SQL.
Listing 10.9 A script to create a role with all privileges of a schema table owner.
spool /tmp/&1.role.sql
select '— Create the two new roles. ' from dual;
select 'create role &1._role_manager identified by xxx;' from dual;
select 'create role &1._role_ROLE_SELECT identified by xxx;' from dual;
select '— If there were select privileges, ' from dual;
select '— grant these selects to _role_ROLE_SELECT. ' from dual;
owner = '&1'
and privilege = 'SELECT';
select '— If the users were granted to specific privileges, ' from dual;
select '— grant these privileges to the new role. ' from dual;
select '— If the privilege was granted to PUBLIC, ' from dual;
select '— grant the privilege to all system users.' from dual;
select '— If the privilege was granted to specific users, ' from dual;
select '— grant the role to those users ' from dual;
select '— Revoke all table-level privileges for the owner. ' from dual;
spool off;
There is a general philosophy regarding WebServer security and Oracle: Create a framework to manage
security in a simple fashion. To achieve simplicity, the following guidelines are strongly recommended:
To audit a distributed Oracle WebServer application, each remote database must be checked for unusual
grants and situations where a user has received privileges (either system or object privileges) from an
unauthorized source. As each database is visited, an audit file will be produced for the DBA to review. The
database dictionary can be interrogated to show the following security breaches:
• Any system privileges granted with admin option (DBA_SYS_PRIVS table)—Remember, this
scenario can be a danger because anyone who receives a system privilege with admin option may
grant his privileges to others.
• Any non-DBA roles granted with admin option (ROLE_SYS_PRIVS table)—All system
privileges and roles can be granted with admin option, and it’s important to ensure that roles aren’t
floating around that could be granted to others.
• End users with table privileges grantable to others (DBA_TAB_PRIVS table)—End users who
have grant option object privileges. Just as system privileges and roles can be granted with admin
option, object privileges can be granted with grant option. It’s important that nobody (except table
owners) may grant table privileges to others.
• End users who have received a grantable privilege (ALL_TAB _PRIVS_RECD table)—Anyone
who receives a system or object privilege from anyone except SYS will be reported in this list. The
person who granted the privilege will appear in the grantor column, and it should correspond to a
grantee name in DBA_TAB_PRIVS and/or DBA_SYS_PRIVS. If the offending grantee has his
admin or grant option revoked (i.e., revoke privilege from grantee cascade constraints), the
revoke should cascade into ALL_TAB_PRIVS_RECD, and these entries will disappear.
• End users with roles (other than resource and connect) (DBA_ROLE_PRIVS table)—This
table lists any roles other than resource and connect for all users except OPS$ORACLE, SYS,
SYSTEM, and DBA. This table will show anyone who has wrongly acquired DBA privileges.
• End users with system privileges (DBA_SYS_PRIVS table)—This table shows all users who
have system privileges. In some cases, it’s okay for a user to have unlimited tablespace, but other
privileges such as drop table should be carefully monitored.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select In any Oracle environment, it’s a good idea to check for unusual security conditions on a regular basis.
Listing 10.10 shows a script used to check for unusual Oracle security.
***************************************************
prompt Searching &1 for system privileges granted WITH ADMIN OPTION...
select * from
dba_sys_privs
where
admin_option = 'YES'
and
grantee not in ('DBA','SYSTEM','SYS','OPS$ORACLE');
***************************************************
prompt Searching &1 for non-dba roles granted WITH ADMIN OPTION...
select * from
role_sys_privs
where
role <> 'DBA'
and
admin_option = 'YES';
***************************************************
prompt Searching &1 for table privileges that are grant-able to others...
select substr(grantee,1,12), substr(table_name,1,20),
substr(privilege,1,10), substr(grantable,1,3)
from
dba_tab_privs
where
grantable = 'YES'
and
owner not in ('SYS','SYSTEM','GL','APPLSYS','BOM','ENG',
'PO','AP','PER','WIP','LOGGER');
***************************************************
prompt Searching &1 for users who have received a grantable privilege...
select * from
all_tab_privs_recd
Where grantable = 'YES'
and
owner not in ('SYS','SYSTEM');
***************************************************
prompt Searching &1 for folks with roles (other than resource/connect)...
select * from
dba_role_privs
where
granted_role not in ('RESOURCE','CONNECT')
and
grantee not in ('OPS$ORACLE','OPS$ADMOPR','DBA','SYS','SYSTEM');
***************************************************
Once a set of roles has been established and all grants to public have been removed, an audit script can be
used to ensure that there are no holes within the role framework.
As each database is visited, an audit file will be produced for the DBA to review. As you can see in Listing
10.10, the Oracle dictionary can be interrogated to show all security breaches. Another method of security
auditing is to use a script to show the privileges contained within a role, as shown in Listing 10.11. The
script in Listing 10.11 accepts a role name and produces a report that shows all of the role’s users and
privileges. Be wary when you run this script, though, because it can be a huge report, with many thousands
of lines of output.
Listing 10.11 role.sql <role_name> showing all role users and privileges.
Role
—————
EXP_FULL_DATABASE
IMP_FULL_DATABASE
Role Grantee
—————————————————————————
DBA ORADBA
SYS
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Listing 10.12 is another SQL script useful for showing role information. Listing 10.12 shows all the roles
within Oracle, all system and table privileges that comprise each role, and finally, all users who have been
granted each role. Again, be forewarned that this can be a very large report if the Oracle instance has many
roles.
rem roles.sql - Shows all roles with database and all users (huge report)
SQL> @roles
Fri Mar 8 page 1
Roles in Database
Role SUBSTR(GRANTED_ROLE,1,30)
————— ———————————————
DBA EXP_FULL_DATABASE
IMP_FULL_DATABASE
2 rows selected.
—————
ORORACLEUSR ORACLE.CUSTOMER DELETE
INSERT
SELECT
UPDATE
ORACLE.CATALOG DELETE
INSERT
SELECT
UPDATE
ORACLE.CHOICE DELETE
INSERT
SELECT
UPDATE
ORACLE.DATES DELETE
INSERT
SELECT
UPDATE
ORACLE.MASTER DELETE
INSERT
SELECT
UPDATE
ORACLE.CUSTOMER_TYPE SELECT
Role Grantee
————— —————————————————————————————————————————————————
ORACLEDEV bob_papaj
mark_reulbach
sarah_papaj
eddie_papaj
bryan_papaj
rebecca_papaj
stephanie_papaj
debbie_schumacher
ORACLEUSR EMANS
GENERAL
KRAMER
For very large WebServer applications with more than 50 remote databases, the propagation of database
code and audits can become a major headache. The script shown in Listing 10.13 can be used in a Unix
environment to read a list of remote processors, access each one, find all databases on each processor, and
perform the same function on each database. The script in Listing 10.13 has been used to run SQL security
audits on more than 70 distributed databases, all from a single task on the master processor.
Listing 10.13 Korn shell script used to visit each Oracle database on a host.
done
done
The increasing sophistication of software tools used to manage role-based security is making significant
inroads, but there is still a need for DBA staff members to control data access and to customize unobtrusive
security frameworks. As end users continue to demand more and more seamless access to distributed
information, increasingly sophisticated role-based security frameworks will have to be devised.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
In order to get started with Oracle security, the following guidelines can be followed.
While these are very general security guidelines, they can be used as a starting point
for the development of a comprehensive set of Oracle WebServer security access rules:
1. The DBA is ultimately responsible for Oracle security. Hence, the DBA is
responsible for the creation and maintenance of all Oracle roles.
2. All privileges (both object privileges and system privileges) will be placed
into roles. Privileges will never be directly granted to end users. **
3. All roles will be protected with a password, and the role password will be
embedded into the application so the end users will never know the passwords
for the roles that they have been granted. (This is to alleviate the problem of
end users bypassing an application and issuing updates within MS-Query or
SQL*Plus.)
4. Thou shalt never grant any system privileges with ADMIN OPTION, nor
any table privileges with GRANT OPTION.
5. Only one end user shall be the role administrator (RA). The RA will be
responsible for granting the roles to the end users, and will be granted ADMIN
OPTION for each role that they administer. A special role called “RA” shall be
created with the CREATE ANY USER privilege and granted to the RA.
6. The RA will have neither DROP ANY USER nor ALTER ANY USER
privileges. The DBA will be responsible for dropping end-user IDs, and each
end user will be responsible for maintaining their own Oracle passwords, either
via MS-Query, SQL*Plus, or through an application screen.
7. Only the SYS and SYSTEM users shall be granted the DBA role.
Summary
This chapter covers the basic WebServer form functions. After reviewing this chapter,
you should be able to create WebServer pages that access and update Oracle databases
and manage WebServer security. Next, the following chapters will take a look at
managing entire WebServer-based applications, including addressing issues such as
concurrency, lock management, performance, tuning, and distributed WebServer
applications.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 11
WebServer Navigation And Concurrency
Management
Ever since the introduction of online systems, developers have had to face the
challenges of managing transfers between online screens. When database technology
was introduced, the database interscreen transfer became even more challenging, and
developers had to maintain currencies. These currencies enabled end users to return to
a database at the same point where they left off.
Today, we are using Web pages as the vehicle for screen display, but the principles
that applied to BMS screens with CICS in the 1960s still apply to interscreen
management of WebServer pages.
Interscreen Transfer
For Oracle databases, the concept of database currency means saving all of the rowids
for all current Oracle rows on the Web page. Traditionally, there have been three ways
that a developer could manage a transfer between the current screen and a destination
screen:
• Invoke—An invoke retains database currencies from the current screen and
makes them available to the destination screen. In other words, a current Oracle
row will be available to later screens for processing. For example, say screen
sh100 displays customer information, screen sh200 displays order information,
and screen sh300 displays order detail information. As the end user invokes the
lowest level sh300 screen, the current Oracle CUSTOMER table rowid and
ORDER table rowid are known to the sh300 screen, and these values can be
used in SQL as needed.
• Transfer—A transfer allows for movement between screens without any
maintenance of database currencies. For example, if you transferred from
screen sh100 to screen sh200, then transferred back to screen sh100, the
database information about your previous visit to screen sh100 would not be
retained.
• Link—A link is a one-way transfer to a destination screen with an immediate
return to the current screen. Link screens are generally used to display
exception information (error screens) or show detail (detail screens), and they
immediately return to the invoking screen after displaying the message. In
general, a link can be thought of as a subroutine call, such as a call to a
calculation function.
For WebServer, the decision of whether to invoke, link, or transfer is the same as with
any other type of Oracle application. The difference with WebServer lies in the way
screens are processed by the Web pages. In WebServer, there are several ways to
move to a new screen:
Note: There are two ways to specify the destination screen name with the htp.
formSubmit procedure. One method is to code the screen name (which is a
stored_procedure name) directly in the formSubmit statement, or you may
use htp.formHidden to send the contents of a field along with the submitted
form.
Interform Communication
Just like any other database application, WebServer applications will have an overall
structure. There will generally be some form of main menu, with sublevels of screens
that branch from the menus. The design of the menu hierarchy is the starting point for
most online applications, and this function has not changed with Oracle WebServer
(see Figure 11.1).
At this point, most of the basic rules of online application development apply, and the
fact that the output is displayed in a Web page is only an additional consideration.
However, there is one interesting feature worth noting. In most application designs,
each submenu has an exit function, which will return control to a higher menu. When
using WebServer, these exit functions are not necessary because it is a simple matter
for users to select the Back button on their Web browsers to return to a Web page.
For any database that has many end users updating tables, a method must be used to
ensure that each update transaction does not overlay the updates of the other end users.
This method is generally called concurrency management, and it is a very important
topic for WebServer applications. While most commercial database products provide
for locking and concurrency control, there are new issues when using a distributed
WebServer database. These problems are especially prevalent when a single Web page
updates several databases. In addition to the technical issues, the popularity of Web-
based interfaces has also changed how concurrency is handled. Many Web-based
Oracle systems disable their database locking and rely on procedural tricks to maintain
data integrity. The following sections of this chapter explain the basic features of
database access control and describe the issues involved when concurrency and
database integrity must be maintained in a Web-based environment.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
To illustrate, consider an example where a user displays order information, waits five
minutes, then issues an update of the order information. If we process in full
conversational mode, there is never a problem of database corruption because
exclusive record locks are held for the entire duration of the terminal session.
However, the resources required to hold the locks may cause a burden on the database,
and the lock will impede other transactions that want to retrieve (and possibly update)
the information being held by the session.
Oracle database locking can take place at many levels. For Oracle relational databases,
the locks can be set for an entire table within the tablespace or a row within the table,
both of which are shown in Figure 11.3.
Oracle offers two types of locks: shared and exclusive. The most common type of
locks are shared locks, which are issued with SQL select statements. Exclusive locks
(sometimes called preemptive locks) are issued with delete and update statements. In
shared locking, whenever a unit of data is retrieved from the database, an entry is
placed in the database storage pool. A lock records the unit ID of the item being
locked, which is usually a rowid or database page number. The lock consumes 4 bytes
for each row stored in the Oracle shared pool. This lock will be held by the database
until a commit, end, or abort message releases the lock.
Most locking schemes use a coexistence method. For example, many clients may have
shared locks against the same resource, but shared locks cannot coexist with exclusive
locks. Whenever an update event occurs, the database attempts to post an exclusive
lock against the target row. If any other tasks hold a shared lock against the target row,
the exclusive lock will wait (see Figure 11.4).
The locking scenario displayed in Figure 11.4 ensures that all database integrity is
maintained and database updates do not inadvertently overlay prior updates. However,
there is a penalty for maintaining shared locks. In most databases, a lock requires 4
bytes of RAM storage within the storage pool, and large SQL select statements can
create SOS (Short On Storage) conditions that can cripple the database. For example, a
select statement that retrieves 1,000 rows into the buffer will require 4,000 bytes of
lock space. This condition can also cause the deadly embrace, or DB-KEY deadlocks.
A deadlock condition occurs when two tasks are waiting on resources that one of the
tasks has locked (see Figure 11.5).
Oracle only issues locks against rows when it needs to, so programmatic solutions can
be used with WebServer applications to minimize the amount of locking used for very
large update tasks. For example, in Oracle SQL, a programmer can use the select…for
update clause to explicitly lock a row, or a set of rows, prior to issuing the update
operation. This will cause the database to issue exclusive locks at the time of retrieval
and hold these exclusive locks until the task has committed or ended. In the following
SQL code, an exclusive lock is placed on the target row, and no other tasks will be
able to retrieve that row until the update operation has completed:
Select *
from EMPLOYEE
where emp_name = 'Burleson'
for update of salary;
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select For large updates, statements can be issued to lock an entire table for the duration of
an operation. This is useful when all rows in the table are going to be affected, as in
the following salary adjustment routine. The nowait option will return control to you
immediately, along with a message stating whether the table you are accessing is
locked by another user. Without this option, Oracle would wait until the table became
available, lock the table to perform an operation, and return control back to the user.
The following snippet of code shows the use of the nowait statement:
update EMP_TABLE
set salary = salary * 1.1;
There are times when the application wants to update all of the rows in a table, but it is
not practical to lock the entire table. An alternative to the exclusive update is to use the
SQL fetch statement to lock a small segment of the table, perform the update, and then
release the locks with a commit statement, as shown in Listing 11.1.
select rowid
from EMP_TABLE
where emp_name = :my_emp_name
for update of salary;
begin
count = 0;
open total_cursor;
begin_loop;
open update_cursor;
fetch total_cursor into :my_emp_name;
fetch update_cursor into :my_rowid;
if (update_cursor%found) then
{
update EMP_TABLE
set salary = salary * 1.1
where
rowid = :my_rowid;
count++;
close update_cursor;
close total_cursor;
end;
As you can see, locks are set as the rows are fetched—20 at a time—and then released
with a commit. This technique consumes less memory in the lock pool and allows
other SQL statements to access other rows in the table while the update is in progress.
Of course, if this code fails, it would need to be restarted from the point of the last
commit statement. This requires additional logic to be inserted into the update
program to record the rowid of the last commit ted row, and to restart the program
from that row.
every row that the SQL statement addresses. This can lead to very heavy resource
consumption, especially for SQL statements that update numerous records in many
tables. For example, an SQL query that selects many but not all of the records in a
school’s REGISTRATION table might state:
select *
from REGISTRATION
where
REGISTRATION.grade = 'C';
Depending on the number of students affected, this type of query will begin to hold
row locks until the task has successfully completed or until the SQL statement
terminates due to a lack of space in the lock pool. However, if the database supports
lock escalation, the database will set a single lock for the entire table, even if only a
portion of the rows in registration are affected.
If the statement select * from REGISTRATION is issued to return all rows in the
REGISTRATION table, the database will escalate from row-level locking to page-
level locking. If the REGISTRATION table resides in a single tablespace, some
database engines will escalate to tablespace-level locking. This strategy can greatly
reduce resource usage on the lock pool, but some lock mechanisms will escalate locks,
even if it means that some rows are locked when they are not used by the large task.
For example, select * from EMPLOYEE where department = ‘finance’ may cause
the entire EMPLOYEE table to lock, preventing updates against employees in other
departments.
Whenever possible, large SQL updates should be run using table-level locks, thereby
reducing resource consumption and improving the overall speed of the query. Some
implementations of SQL provide extensions that allow for the explicit specification of
the locking level and granularity. This mechanism could allow exclusive locks to be
placed on a result set if the user intends to update the rows, or to turn off shared locks
if the rows will never be updated.
In Oracle, the engine must know that a row is free before altering any values within
the row. The database accomplishes this by issuing an exclusive lock on the target
row. The exclusive lock mechanism then sweeps the internal lock chain to see if
shared locks are held by any other tasks for any rows in the database. If shared locks
are detected, the update task will wait for the release of the shared locks until they are
freed or until the maximum wait time has been exceeded. While the task is waiting for
the other tasks to release their locks, it is possible that one of these tasks may issue an
update. If this update affects the original task’s resources, a database deadlock will
occur, and the database will abort the task holding the least amount of resources.
update REGISTRATION
set REGISTRATION.grade = 'A'
where
course_id = 'CS101'
and
COURSE.instructor_id = 'BURLESON';
This single statement may update many rows, and the Oracle concurrency manager
must check for contention (i.e., shared locks). If any other tasks are viewing any other
rows in the database, the engine will set as many exclusive locks as it can and put the
statement into a wait state until the shared locks from other tasks have been released.
Only after the desired rows are free will the transaction be completed.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The problems of lock pool resources and database deadlocks have lead to some
creative alternatives to shared and exclusive locks. Locking can be turned off in any
database by issuing a commit statement immediately after the select statement.
Without long-term shared locks, lock pool utilization is reduced, and the potential for
database deadlocks is eliminated. But, we still must deal with the problem of ensuring
that updates are not overlaid. Consider the example of updates without locking shown
in Figure 11.6.
Both tasks have selected Burleson’s employee record and issued commit statements to
release the locks. Task B now changes Burleson’s performance rating and issues an
update, which writes the column back to the database. Task B, which is now looking
at an obsolete copy of Burleson’s performance_flag, changes the salary, improperly
assigning Burleson’s raise. This is a type of logical corruption whereby a user relies on
outdated values in other rows, then updates the target column based upon the obsolete
information.
Some databases, such as SQL/DS and Oracle, allow select for update commands.
With select for update, the before image of the row is compared with the current
image of the row before the update is allowed. However, since it is not recommended
that Oracle WebServer applications use select for update, there are a couple of clever
techniques you can use to release all Oracle locks and still maintain database integrity.
For example, if Burleson’s row contains the performance_flag, salary, and name
columns, each of the columns will be specified in the update command, even if the
user has not changed the column (see Figure 11.7). Using this method, if any of the
values have changed since the row was initially retrieved, the database will reject the
transaction with a not found SQL code. The WebServer application could interpret
this code, re-retrieve the updated record, and present it to the user with its new value.
Note: It is very important to run the explain utility with this type of update
statement to be sure that the SQL optimizer uses the employee index to locate
the row. With so many items in the where clause, some optimizers may
become confused and service the request by using a full-table scan, causing
significant performance delays. Some implementations of SQL allow the
programmer to specify the index that will be used to service the query, while
other implementations of SQL require that the indexed field be specified first
in the where clause. Regardless, it is important to run an explain plan on the
SQL to be sure that the additions to the where clause do not impede
performance.
Some databases have SQL extensions that can explicitly turn off unwanted indexes.
Oracle, for example, allows indexes to be turned off by altering the key field used in
the where clause. Assume that EMP_TABLE has the following definition:
Let’s further assume that emp_name has a unique index, and the fields sex,
performance_flag, and salary have non-unique indexes. To ensure that the index on
emp_name is used, the index key fields will be altered by concatenating a null string
to the end of the char columns and adding a zero to the end of each numeric column.
Hence, the SQL update would read:
Update EMP_TABLE
set salary = salary*1.05
where
emp_name = 'Nally' and
performance_flag+0 = 9 and
sex !! "" = 'M' and
salary+0 = 20000;
There is another method to ensure that the emp_name index will be used. We could
alter the emp_name index to include the nonunique fields of sex, performance_flag,
and salary, creating a large concatenated index on every column in the table. There
would be a slight index overhead, but you can be assured that all index updates
perform efficiently without relying on the SQL programmers to alter their SQL.
This solution requires that a date-time stamp column be added to each table that may
be updated. All applications are required to select this column and include it in the
where clause when issuing any update SQL. Of course, if the row has changed, the
date-time stamps will not match, and the transaction will fail with a not found SQL
code.
Whether the manager chooses to purchase an API or create a custom API, it is very
important to realize that the nature of the data access can tremendously impact the
complexity of the processing. For read-only databases, API processing is relatively
simple, but for systems requiring cohesive updating, the processing problems increase
exponentially. In fact, it is impossible to implement any cohesive updating scheme
with 100 percent reliability.
There is an inherent updating problem with distributed databases that is common to all
systems. This particular updating problem occurs when a federated database attempts
to simultaneously update two distributed databases. Commonly known as the two-
phase commit (2PC), the procedure is illustrated in the following example:
Apply update A
Apply update B
If A-OK and B-OK
Commit A
<===="Here is the deadly exposure"
Commit B
Else
Rollback A
Rollback B
As you can see, updates A and B get posted to the database. If the SQL code indicates
that each transaction has completed successfully, then the system will issue commit
statements to A and B. The point of exposure occurs when a failure happens after the
commit of A but before the commit of B has been completed. Of course, the exposure
can only happen when the failure occurs at the exact instant between the commit of A
and the commit of B, but it is an exposure that has a potential to cause a major loss of
integrity within the database, and an exposure for which there is no automated
recovery. The only remedy is to notify the DBA that the transaction has terminated
and manually rollback the updates to A and B. This type of corruption has a very small
probability, and most databases do not worry about this exposure.
Summary
Concurrency control has become a pressing issue due to the increasing popularity of
client/server systems. As client/server systems become more mature, we will begin to
see concurrency methods that can automatically manage updates to distributed
databases. In the meantime, the developer must decide which of the update control
mechanisms is best suited to the operation of their distributed database.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 12
Using Java And LiveHTML With Oracle WebServer
The method for processing requests through the PL/SQL cartridge of Oracle
WebServer is discussed in detail throughout the previous chapters of this book. In this
chapter, we’ll discuss the other two major cartridge components of Oracle WebServer
2: the Java Interpreter and the LiveHTML Interpreter. The Java and LiveHTML
cartridges work with the Web Request Broker to build dynamic content into Web
pages. In addition, LiveHTML enables information to be included in documents from
sources on the server, such as the output from executing Unix shell scripts.
Java
Java is a very new technology that enables the execution of code (called applets) that
can be distributed across heterogeneous computer nodes on the Internet. It provides an
object-oriented, secure, portable, high-performance, full-featured development
environment for generating interactive 3D Web documents, intelligent agents, and self-
updating software.
Java provides the ability to run the same applet on any machine that has a Java
interpreter. In addition, Java has minimized the porting requirements of code down to
only one applet for each application to interpret and execute. The dynamic
presentation of Java applets on a Web page is a remarkable spectacle to behold.
Instead of the basic hypermedia of text and images that we are accustomed to, the
dazzling effects of these self-contained applications can be interactive in nature. To
date, Java applets are used to animate image icons, so the Web page appears to be
constantly in motion with dancing icons.
Development Of Java
As many of you are aware, Java is a product of Sun Microsystems. Its development
began in 1991 as a special project named Green to sell software technology to
consumer electronics companies. One of the key goals of the Green project was for the
software code to be platform-independent, because developing for only one platform
tremendously limits a product’s marketability. In addition, subsequent roll-outs to
every other platform is a developer’s nightmare that often consumes too much capital
to make the venture successful. The original name of the Java language was Oak, but
the name had to be changed due to it not passing a trademark search. Java was initially
intended to be developed using C++, but the primary developer, James Gosling, found
its structure too complex for accomplishing their objectives.
Originally, there were four components of the startup product including the language
(Oak), an operating system called GreenOS, a user interface, and a hardware device,
all fused together into a hand-held unit called *7. The first application for this
technology was targeted on consumer electronics manufacturers to place the Sun logo
on the front of television boxes. During this time, Time-Warner was soliciting the
industry for set-top box operating systems and technology to provide video on-
demand. The set-top box would be used to decode the data stream that entertainment
companies would be sending to consumers for display on television sets. The Green
project was renamed at this time to FirstPerson Inc.
The focus of the Java project then shifted from the television market to the World
Wide Web, which had the same need for small, platform-independent code. At about
this time, the first graphical Web browser called Mosaic was released, and, for the first
time, Web surfers enjoyed the merging of graphics and text into Web documents. The
Web continued to grow at a staggering pace, mainly due to the improvement in
bandwidth on the Internet. Seeing the potential market for their software expanding
rapidly, substantial resources were brought to bear by Sun to finalize the development
of the Java environment.
During the latter half of 1994, a Web browser called HotJava was developed and was
followed soon thereafter by the Java language. The public announcement of the Java
environment occurred on May 23, 1995 at SunWorld ’95. Since that date, the fortunes
of Java have continued to grow, due in large part to its incorporation into Netscape
Navigator, the most popular browser on the Web.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Because of its interpretative nature, Java is a programming language that can execute
on any computer. Java begins as Java source code, which must be compiled into Java
Virtual Machine bytecode before it can be transmitted to a receiving host machine.
When a client receives a Java bytecode applet, the Java Interpreter is invoked to
translate the bytecode into the native machine code for the receiving client. Thus, Java
is both compiled (at creation time) and interpreted (at execution time). (See Figure
12.1.)
Java is an interpretive language that requires the computer running it to have a Java
interpreter to convert the Java code into the computer’s machine code. Because Java is
an interpretive language, the Java code does not have to conform to each and every
hardware platform. The Java compiler generates executable code from the source code
by first compiling for a hypothetical machine called the Java Virtual Machine, which
resides on the computer where the applet is to be executed. Some of the operating
systems that currently support the Virtual Machine include Windows, Solaris, MacOS,
OS/2, Linux, Amigo, and a few others. Language interpreters have traditionally
suffered from poor response time, but Java has improved this process by compiling to
an intermediate stage (the Virtual Machine), where the source code is converted to
bytecode. This bytecode is not executable by any machine, but must be converted to
the native code for a specific machine to understand. This feature of easily converting
The portability of Java is not only enabled by the virtual machine specification, but
also by the requirement that data sizes will always consume the same amount of space,
regardless of the host computer. In Java, datatypes (such as integer) are specified in
only one length. This is not the case for C programming languages that may change
depending on the underlying hardware and operating system. For instance, an integer
that has a length of 16 bits in Windows 3.1 now requires 32 bits in Windows 95.
Computer processors have the same inconsistency in this area, which is illustrated by
the Intel 486 being defined as a 32-bit machine and the DEC Alpha as a 64-bit
machine. Because data sizes are always the same within Java, the programs are
hardware-independent.
Java has often been described as C++ without the pointers. One of the other portability
issues that differentiate Java from C++ is that C++ allows the use of pointers to
directly access memory locations. In addition, Java does not allow automatic memory
management. Because Java does not use pointers, there is less likelihood that portions
of memory could be corrupted by faulty addressing. However, the lack of pointers
makes Java far less robust than C++. It is impossible to link Java objects together, and
each Java class must encapsulate all of the functionality that it requires. Memory
management within Java is accomplished by the program keeping track of objects and
references to those objects. When an object has no more references, it is removed from
memory by a job running in the background.
The object-oriented design of Java is one of its best attributes and is certainly in line
with the future direction of application code. Object-oriented code has several benefits,
including:
functional classes. The classes can be dynamically loaded whenever they are needed to
perform repetitive processes. The Java applications can alter their functionality by
linking additional classes at any time to perform other tasks. The class definition is
used twice during the life of a Java object. The class definition is first used at object
creation time to define the data structures for the object, and then is referenced at
runtime when a behavior is requested.
Every object has a state, which is its status at a given point in time. For example, the
state of the object radio could be one of the following:
• Radio on
• Radio on and tuned
• Radio on and not tuned
• Radio off
Click Here!
Click Here!
ITKnowledge
Please Select The state of a class is represented by instance variables that are managed locally by a
specific class and, in most cases, are not globally available to other classes. Changing
the state of the class is accomplished through methods, which are associated with a
specific class, just like the local instance variables. In other words, the method is the
code that performs functions for the class to modify its status. In the example for the
radio object, a method could be the radio buttons to turn the radio on or off, or to tune
the stations.
Another base feature of the object-oriented environment is inheritance. Let’s say that
the radio class was originally defined as an AM radio. Instead of writing a whole new
set of code to define the radio for FM, you could simply create the new FM radio class
and have it inherit the properties of the AM radio class. Then, you would only need to
make minor code adjustments to change AM to FM. This new class would be referred
to as a subclass of the original class, which is now described as a superclass of the
new one. This relationship between subclasses and superclasses can save tremendous
amounts of time in coding extensions to the functionality of existing objects, because
all objects inherit the data definitions and behaviors of their superclasses.
Within the Java class, variables and methods are accessed via the following privilege
categories:
• Friendly—Allows all packages in the same package to use the methods and
variables. This is the default category for access if none is specified.
Security Of Java
There are several features of Java that enhance the security of distributed processing,
including a bytecode verifier, runtime memory layout, and restrictions on file access.
When the interpreter receives the Java bytecode, it reviews it for language compliance.
This is done to ensure that the code was not altered since it was compiled, which
sometimes occurs inadvertently. If the code passes this step, then the interpreter
defines the memory layout for the classes. Because the memory layout is dynamically
created for a specific computer configuration, the chances of a surfer guessing the
structure of a class for unauthorized access is minimized. After the memory layout is
generated, the interpreter reviews the intended file accesses of the loaded classes. If
the file accesses are inconsistent with those permitted by the client, then the request is
rejected.
Performance Of Java
• Multithreading
• Efficiency of bytecode
• Linking of native C code
In single-threaded applications, programs must wait for user input, file availability,
and network access. During the times that the applications are waiting, the processor is
idle, because it has no requests to process. Requests become bottlenecked in a queue
behind the first process waiting for resources. On the other hand, Java can break down
a request into several different processes that execute independently and
simultaneously, which provides much greater efficiency in process throughput. The
tools for managing the threads are built into Java, thus reducing the reliance on the
operating system for this feature.
Another positive performance feature is that the compiled Java bytecode is very
similar to native machine code, so the process of interpreting this code is very efficient
and straightforward. This certainly was the intention of Java developers—to make the
conversion a simple task on any machine and to minimize the machine resources
allocated to the task.
Finally, Java provides an option to link native C code into an application. This is very
efficient and provides a faster implementation than having to compile code at runtime.
Of course, more work is involved for the programmer, who would have to incorporate
the linking component into the code.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The file containing the Java source code should have the extension .JAVA appended
to the file name. Java source code is the code that will be compiled to bytecode. Java
programs can contain several of these compiled units. Compiled units in Java are
defined with any of the following four structure elements:
• Package statements
• Import statements
• Class declarations
• Interface definitions
The class declaration is used extensively for specifying instance variables and
methods, as well as static variables and methods.
All source code must have a main() method defined; this indicates to the interpreter
where to start running the program. The basic structural elements of Java source code
are outlined in Listing 12.1.
import classname
class classname {
public static void main (String args[]) {
// source code
}
}
The source code is added into the main() method, which receives arguments from the
interpreter (String args[]). The method does not return any variables (void), is the
same for all occurrences of the class (static), and can be executed by any class
(public). If the program requires the use of this method, then the import statement is
needed to load in the previously compiled class code. The import statement can also
import C code and Java packages, and allows code to be loaded into the applet for use
in a number of places. Importing a package will load all classes within that package
into the program.
Packages can be utilized by specifying a fully qualified class name for the class to be
executed. This name is comprised of the class name appended to the end of the
package name. An example of code using the class Date within package java.util is
presented in Listing 12.2.
Using the fully qualified class name is useful for loading a class from a package into
one location in a program, and also when you only want to load one class from a
package.
The interface definition is similar to the class definition, but there are some
differences. First of all, the interface keyword is used instead of the class keyword in
the definition statement. Secondly, interfaces can extend other interfaces through the
use of the extends keyword. Interfaces have an inheritance chain just like classes,
whereby interfaces can be subclassed by using the extends keyword in the definition.
For instance, you could put all your constant values into one interface, so that they
could be used in classes that do not need to implement a method. An example of such
an interface appears in Listing 12.4.
To reference the interfaces Build_matl and item_cost within the class Classname, the
implements keyword is used, as displayed in Listing 12.6.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The Java Interpreter is the cartridge within Oracle WebServer that allows for the
execution of Java on the server to generate dynamic Web documents. In Oracle
WebServer 3.0, Java is used to create and maintain Web pages, such that the
WebServer is only required to refresh the data portions of a Web page.
Note: Remember that cartridges used by the Web Request Broker to build
different functionality into Web pages include the PL/SQL Agent, the Java
Interpreter, and the LiveHTML Interpreter. Of the three cartridges, the Java
Interpreter has the best and most varied functionality, while the PL/SQL
Agent provides the most efficient database access method. The LiveHTML
Interpreter is Oracle WebServer’s implementation of Server Side Includes
(SSI), which enables the output from programs executed by the operating
system to be inserted into Web pages.
Note: Java technology is a perfect fit for Oracle’s future direction in the area
of building Network Computers. The basic idea behind the NC is a low-cost
computer containing a small amount of memory, a fast processor, and a
connection to the Internet. The NC would not have a hard drive or a floppy
disk drive, instead relying on the Internet for applications, such as Java applets
and storage.
Downloaded Java applets have the ability to interface with other applets, and
applications can be built on a combination of these applets from across the Internet.
Remember, it is the bytecode created by the compilation of Java source code that is
transferred throughout the Web.
Oracle WebServer enables the execution of Java either on the client or on the server.
(See Figure 12.2.) It is possible to embed calls to Java applets within Web pages that
can be executed by any Java-enabled browser. A good way to implement client-side
Java applications is to store the code on the file system of the local operating system,
and then execute it on an as-needed basis.
Java can execute the PL/SQL code stored in an Oracle database by initiating a process
through the Java Interpreter component of Oracle WebServer. In this scenario, the
Java Interpreter does not utilize the PL/SQL Agent to satisfy the incoming HTTP
request against the database, as is the case with PL/SQL requests that are mapped
directly through the PL/SQL Agent. The PL/SQL code to be executed is stored in the
Oracle database and thus could be ported to any other Oracle database for processing
on a different server.
This feature provides developers with the flexibility to build their WebServer
applications by sharing code across different applications on Oracle instances, as well
as porting the applications easily through the system development life cycle, from
development to production. As you remember, Java applets are also portable to any
platform due to the compilation of its source code for the Java Virtual Machine. The
combination of both the PL/SQL and Java code being highly portable makes Oracle
WebServer a powerful tool for developing Web applications because the whole idea of
the Web is to share information easily and rapidly.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
The Java Interpreter is the mechanism that interprets and executes Java code within Oracle WebServer
on any platform. There is no additional software installation required to use the Java Interpreter for
executing Java code; the installation of Oracle WebServer includes this component.
Note: If you want to interpret JavaScript, you must download the JavaScript Interpreter from
www.javasoft.com.
The server-side requests processed through the Java Interpreter are via the Web Request Broker, which
dispatches them to the cartridge. Using the WRB as the gateway interface for these requests is
determined by your virtual directory mappings for the WRB that are defined through the WebServer
Administrator Web page. In essence, these virtual directories are associated with the physical
directories of the underlying file system.
Note: You can find additional information about virtual directory mappings for WRB and
Oracle Web Listener in Chapter 4, Installing And Configuring Oracle WebServer.
Once a request is executed, the results are returned to the initiating browser through the services of the
Oracle Web Listener.
Oracle WebServer provides a set of Java packages called the Java Web Toolkit, which contains classes
that are extremely helpful in building Java applications. This toolkit is similar to the PL/SQL Web
Toolkit that provides the hypertext functions, hypertext procedures, and OWA utilities included in
packages such as owa_util and owa_text. The Java applications are dynamically defined for interaction
between browsers and databases. As mentioned earlier, PL/SQL packages can be executed from within
Java code to capitalize on the relative strengths of both languages. Java is a very creative tool for
managing graphical images, while PL/SQL provides more efficient database access. The Java Web
Toolkit has wrappers for Java applets. Wrappers enable the storage of applets in Oracle databases. This
feature provides the basis for client-side computing, where the Java Interpreter retrieves wrapped
applets from a database and transfers the code to a browser on the client workstation. The applets are
then embedded into a Web page and subsequently executed. Processing on the client side can also be
accomplished through the PL/SQL Agent in a special situation where the applets are retrieved as data.
Java code may load classes from the Java Web Toolkit by using the import statement, discussed earlier
in this chapter. The groupings of classes to be imported include:
Up until now, all previous database access using PL/SQL code described in this book has involved the
PL/SQL Agent. This is not the case with the execution of PL/SQL from Java, which bypasses the PL/
SQL Agent altogether. If the PL/SQL Agent was processing a request through the Web Request Broker,
then the database connection was maintained for the duration of the request’s processing. The execution
of PL/SQL code within Java is similar to CGI, in that a database connection is initiated for every
request and will add more overhead to the operation.
The Database Connection Descriptors were configured for the Oracle WebServer only and apply to the
PL/SQL Agent for defining the privileges associated with an application. On the other hand, database
connections for Java are specified directly in the code.
Accessing an Oracle database through the Java Interpreter is accomplished by executing PL/SQL within
the database. PL/SQL code can be represented as PL/SQL packages or standalone PL/SQL procedures
and functions. Standalone procedures and functions are those that are not grouped under a package. PL/
SQL packages must have a package wrapper to interface with Java. The package wrapper becomes a
Java class that contains methods for executing the functions and procedures grouped in that package.
Only one wrapper can contain all of the standalone procedures and functions. To create a package
wrapper for a PL/SQL package, execute the pl2java utility as shown here:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select You can specify one or more package names for the pl2java utility to create as wrapper classes. Every
time an applet is executed, an instance of the class will be created to process against the related
package. Separate instances of the class are created to keep the values of local variables distinct from
instance to instance and to allow flexibility in the selection of methods to process. Global variables may
also be used to share data values across class instances. Standalone procedures and functions can be
wrapped with the pl2java utility by not specifying a package name and using the class flags argument.
As previously discussed, all standalone procedures and functions should be contained in one wrapper
class.
• flags—This argument determines how the wrappers will be built. All flags are optional except
class, which may be required in specific situations. The various flags include:
• directory_name—Wrapper classes will be stored in the directory specified by this flag.
If this flag is not specified, the current directory will be the default location for the
wrapper classes.
• help—This flag provides useful information to assist the user.
• class class_name—This flag assigns the package wrapper to a Java class and is
required for wrappers of standalone functions and procedures. No wrapper name is
specified for standalone functions and procedures because they are not grouped within a
package. The class flag is optional for assigning packages to Java classes because Java
class names default to the name of the package being captured.
• package packagename—This flag specifies the name of the Java package that the wrapper
classes are assigned to.
• username—This argument is the name of the Oracle account that owns the packages.
• password—This argument is the password for the database Oracle account that owns the
packages.
• connect_string—This argument specifies the processing information used to connect to the
database where the packages reside. The Oracle System ID (SID) must be specified for
accessing a local database. Accessing a remote database requires information such as the SID
and hostname.
• packagename—This argument specifies one or more package names to be assigned to a
package wrapper. The package name is not specified for standalone functions and procedures,
but the class flag argument is required to name the Java class wrapper.
There are several PL/SQL packages that can cause the pl2java utility to fail when creating a package
wrapper. These incompatible datatypes, along with their replacement datatypes, can be seen in Table
12.1.
Note: PL/SQL datatypes that are incompatible with package wrappers and have no replacement
datatypes include rowid and mslabel.
An example of accessing data in an Oracle database using Oracle WebServer PL/SQL packages was
presented in Chapter 8, WebServer’s OWA Utilities. Now, we will retrieve Oracle data using PL/SQL
packages from within Java code. Here, we are utilizing the strength of the PL/SQL packages—efficient
database access—combined with the versatility of the Java language. Listing 12.7 displays code for the
PL/SQL package Hosts, which contains the procedure list_hosts. This procedure will perform an SQL
query from within the PL/SQL code for its package body found in Listing 12.8. The data retrieved from
table HOST (shown in Listing 12.9) includes host names, Oracle CSI numbers, and a count of the hosts
associated with the same customer.
procedure list_hosts (
custname in varchar2,
hostname out string_table,
oracle_csi_nbr out number_table
);
end;
/
show errors
select count(*)
into hostcount
from host
where cust_name = custname;
return hostcount;
end;
procedure list_hosts(
custname in varchar2,
hostname out string_table,
oracle_csi_nbr out number_table
) as
i number;
cursor host_rcd (custname varchar2) is
select host_name, oracle_csi_nbr
from host
where cust_name = custname;
begin
i := 1;
for hosts in host_rcd (custname) loop
hostname(i) := hosts.host_name;
oracle_csi_nbr(i) := hosts.oracle_csi_nbr;
i := i + 1;
end loop;
end;
end;
/
show errors
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select You can then create a main program for the Java code stored in the file HostRpt.java, as shown in Listing 12.10. The
oracle.html package imported into the program will assist in the generation of dynamic HTML.
import oracle.html.*;
hp.printHeader ();
hp.print ();
}
}
Execute the pl2java utility to create a Java class wrapper for the Hosts package, as follows:
The output code from this utility will be generated into the Hosts.class file on the current directory, as illustrated in
Listing 12.11.
Note: If you encounter the error pl2java: java cannot be executed when running pl2java, then you have
incompatibility between your JDK (which is the Java library) and the Oracle Java interpreter. You may need to
download a different version of the JDK from the Web site www.javasoft.com. The untarring of this
downloaded file will create a bin directory, which then needs to be added to your environmental variable path.
Refer to Oracle bug 373840 for further details on this incompatibility problem.
In order to connect to the Oracle database, a Session object must be created by modifying the main program, as
shown in Listing 12.12. Importing the package oracle.rdbms into the program will make multiple classes with
database functionality available. Session properties are defined for the environmental variables ORACLE_HOME
and TNS_ADMIN using the Session.setProperty function. The variable ORACLE_HOME specifies the location
of the Oracle software executables, and the TNS_ADMIN variable indicates the location of the SQL*Net V2 files
tnsnames.ora and listener.ora for configuring client/server access. The session information specified for the database
login includes the Oracle account, password, and connect_string. To assist in trapping exception conditions, the
login process is enclosed within a try/catch block.
Listing 12.12 Connecting to the database via the main program HostRpt.
import oracle.html.*;
import oracle.rdbms.*;
Session.setProperty("ORACLE_HOME",
“/opt/oracle/app/oracle/product/7.3.2”);
Session.setProperty("TNS_ADMIN",
“/opt/oracle/app/oracle/product/7.3.2/network/admin”);
Session.session;
try {
session = new Session ("www_user", “passwd”, “connect_string”);
} catch (ServerException e) {
bd.addItem (new SimpleItem("Logon fails: ” + e.getSqlerrm()));
hp.print();
return;
}
hp.print ();
}
}
A new instance of the Java wrapper class now needs to be created with methods that will be used to call the
procedures and functions within the Hosts package. Before you can call the stored procedures or functions of the
Hosts package, Java instance variables must be defined for the PL/SQL parameters. An example of a PL/SQL
parameter in this scenario is pCustname. In order to make the transition from generic Oracle PL/SQL code to Java-
wrapped PL/SQL, the PL/SQL tables need to be redefined as Java arrays. This Java class code is displayed in Listing
12.13 for program HostRpt. An additional set of WebServer Java classes called oracle.plsql is imported into the
program to manage PL/SQL datatypes. The new instance of the Hosts package is generated by the statement Hosts
hosts = new Hosts (session); where Hosts is the package name, and hosts represents a field name for the name of
the host.
Note: If you retrieve a PL/SQL value using the value methods, such as doubleValue() of pDouble, it is a good
idea to first validate that the value is not NULL because an error condition will be returned for
NullValueException. The other option would be to handle the NullValueException through the try function.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Sometimes Java will delay its internal cleanup processes before disconnecting the current session. This delay
will hold previously allocated machine resources until the session is terminated so you should log off your
session at the end of the wrapper class code.
Listing 12.13 Wrapper class code for calling the Hosts package within program HostRpt.
import oracle.html.*;
import oracle.rdbms.*;
import oracle.plsql.*;
Session.setProperty("ORACLE_HOME",
“/opt/oracle/app/oracle/product/7.3.2”);
Session.setProperty("TNS_ADMIN",
“/opt/oracle/app/oracle/product/7.3.2/network/admin”);
Session.session;
try {
session = new Session ("www_user", “passwd”, “connect_string”);
} catch (ServerException e) {
bd.addItem (new SimpleItem("Logon fails: ” + e.getSqlerrm()));
hp.print();
return;
}
Hosts hosts = new Hosts (session);
String custname = null;
if ((args.length < 1) || !args[0].startsWith(“CUST=")) {
bd.addItem(new SimpleItem ("No customer name provided"));
hp.print ();
return;
} else {
custname = args[0].substring(5);
}
As with PL/SQL stored procedures, dynamic HTML documents can be created through Java by utilizing the
IHtmlItem interface against Java objects. Java interfaces were discussed in more detail earlier in this chapter.
The specific interface IHtmlItem has two methods (toHTML and print) that in combination will convert the
content of objects to HTML. The toHTML method builds HTML documents in the format of a string, within
a buffer cache, which can be manipulated further from within the class code. The print method extracts
HTML from a buffer and outputs the resultant Web page to system output via environment variables.
Note: The Oracle package oracle.html contains numerous Java classes to assist your development of
dynamic documents. You can also create home-grown HTML classes by deriving them from the
Container and CompoundItem classes. This derivation of properties from existing classes is known as
inheritance in object-oriented parlance.
Just as hypertext procedures and functions (htp and htf) generate HTML tags for the creation of HTML
documents, there are also Java objects that generate dynamic HTML Web pages. Table 12.2 shows these Java
objects and the HTML tags they create. A skeletal HTML document can be built with the HTMLHead,
HTMLPage, and HTMLBody objects. To incorporate the structural elements of the Web page, utilize the
AddItem method for adding HTMLItems to the document body.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Notice in Table 12.2 that various lists can be generated through dynamic Java HTML. Listing 12.14
displays Java code that will create an ordered list.
//Now add the ordered list object to the body of the Java code
bd.addItem(orderedlist);
Listing 12.15 shows the Java code necessary to generate a menu list. The Java code used to create menu
lists is very similar to the code used to create ordered lists.
//Insert the MenuList object into the body of the Java code
bd.addItem(menulist);
The code to create a definition list is a little different from the two previous lists in that the list is
derived from the Container object, as displayed in Listing 12.16.
Listing 12.17 shows the code to create an HTML document. The package oracle.html is imported into
the code to assist in the development of the document.
import oracle.html.*;
}
}
To create an HTML table, see Listing 12.18 for the pertinent Java code.
//Define TableRow
rows[i] = new TableRow();
An HTML anchor can be created by using the Java code illustrated in Listing 12.19.
An HTML form is generated from the Java code shown in Listing 12.20. The form is defined with the
GET method and uses the HTTP protocol.
//The form object built above is now inserted into the object HtmlBody
bd.addItem(form);
Listing 12.21 displays the Java code for executing a client-side Java bytecode applet in a Web
document. The applet file named LilacFest.class processes a parameter and displays text within an
applet window defined with the dimensions of 350 by 50.
LiveHTML
LiveHTML is a very useful tool within Oracle WebServer. Essentially, LiveHTML provides a
mechanism for embedding non-Oracle information into an Oracle Web page.
Oracle has implemented the concept of Server Side Includes (SSI) into its WebServer architecture
through the LiveHTML constructs and the LiveHTML Interpreter. SSI enables the creation of dynamic
Web documents through various methods, including:
To embed LiveHTML within Web pages, LiveHTML must be parsed by the Oracle WebServer, which
is not a requirement for normal HTML documents. LiveHTML is syntactically the same as SGML, so,
unless the code is parsed, it will not be processed by the browser. In Figure 12.3, you can see the Web
Request Broker Administration screen, where you can click on the hyperlink to modify the WRB
configuration for the Oracle Web Listener processing the LiveHTML request. Clicking on the hyperlink
will transfer you to the Web page shown in Figure 12.4, which is used for modifying the SSI cartridge
(LiveHTML Interpreter). Figure 12.5 shows the settings changed to TRUE for the cartridge parameter
ParseHTMLExtn; clicking on the button for Modify Cartridge Configuration will complete the
configuration.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
• config—This command defines how the LiveHTML code will be parsed. The
arguments related to this command include:
• errmsg—This argument allows for the specification of an error
message encountered during parsing.
• sizefmt—When displaying a file size, this argument will determine the
format that will be used. The options include abbrev, which presents the
size in kilobytes or megabytes, and bytes, which obviously presents the
size in bytes.
• timefmt—If any dates are displayed on a LiveHTML document, this
argument defines their formatting, based on the strftime library calls of
Unix.
• cmdech—Passing the value ON through this argument will include
output from a non-CGI script into an HTML page. Passing the value
OFF (which is the default) will not incorporate the output into the
document.
• cmdprefix—This argument passes text that is attached to the front of
for a CGI script to be processed on the server. CGI scripts are widely
used throughout the Web, but product extensions within Oracle
WebServer like LiveHTML are replacing the previously standard
processes with improved functionality.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
In order to appreciate the power of LiveHTML, let’s take a look at an Oracle application that actually uses LiveHTML. In
our example, we start by displaying a Web page that can be used to interrogate Unix environmental information. (See
Figure 12.6). Here, we see that the Web page displays a series of hypertext links to perform different functions on the host
server. This would be a very common application of LiveHTML because the goal of this application is to issue a Unix
host command, capture the output of the command in a Unix flat file, and then display the contents of the flat file on the
Web page.
As you can see in Figure 12.6, the Web page allows an Oracle developer to access information about specific
characteristics of the Unix server. The Oracle developer can press any of the hypertext links to invoke the LiveHTML
embedded in the hypertext links. Listing 12.22 shows the Oracle stored procedure code that generated the Web page in
Figure 12.6.
Listing 12.22 The Oracle stored procedure for the Unix environment query Web page.
create or replace
procedure s99 as
host_name_in varchar2(20);
cursor c1 is
select
host_name
from host
order by host_name;
host_rec c1%ROWTYPE;
BEGIN
htp.htmlOpen;
htp.headOpen;
htp.title('s00');
htp.preOpen;
htp.header(1,' Oracle Information Database');
htp.header(1,' Online Oracle Report Menu','C');
htp.headClose;
htp.preClose;
htp.bodyOpen;
htp.formOpen(owa_util.get_owa_service_path || 's99');
htp.FormHidden('host_name_in', host_name_in);
open c1;
loop
htp.formSelectOption(host_rec.host_name);
end loop;
close c1;
htp.formSelectClose;
htp.anchor('http://hostname.com:8888/ssi/tnsnames.html',
'<h3>tnsnames.ora file.</h3>');
htp.anchor('http://hostname.com:8888/ssi/df.html',
'<h3>File system information. (df -k)</h3>');
htp.FormClose;
htp.bodyClose;
htp.htmlClose;
end;
/
show errors
Now, let’s take a closer look at how this Web page functions. The first option is designed to take a look at the Unix file
system on the Unix server and then display the tnsnames.ora file information on the Web page. The second option issues
a Unix df -k command and pipes the output into a flat file. What’s happening to cause this listing? Let’s begin by
examining the following hypertext link:
htp.anchor('http://hostname.com:8888/ssi/tnsnames.html',
'<h3>tnsnames.ora file.</h3>');
This hypertext link specifies that WebServer is to execute a procedure called tnsnames.html, located in the ssi directory,
as specified in the WebServer directory mapping administration page. Listing 12.23 shows the contents of the tnsnames.
html HTML document.
<HTML>
<HEAD>
<TITLE>LiveHTML (Server Side Includes) Example</TITLE>
<!-- Changed by: Bob Papaj, 14-Nov-1996 -->
</HEAD>
<BODY>
<URL-minder-ignore>
<A NAME="TopOfPage"></A>
</FONT>
</P>
</URL-minder-ignore>
<PRE>
<!--#exec cmd="/u99/dba/oracle/app/oracle/product/7.3.2/ows2/sample/ssi/
tnsnames.csh"-->
<!--#include file="test1.out"-->
</PRE>
</BODY>
</HTML>
In Listing 12.23, you can see some LiveHTML. First, you can see the execution of a C shell script called tnsnames.csh.
Listing 12.24 shows the contents of this script.
#!/bin/csh
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/ch12/423-430.html (4 of 7)4/03/2005 6:16:26
Oracle Databases on the Web:Using Java And LiveHTML With Oracle WebServer
unalias rm
rm *.out
Here we see the execution of several Unix commands. The first step deletes all *.out files on the Unix directory. The next
command executes the Unix echo command to move the current date into a file called test1.out. Finally, the Unix cat
command is used to append the tnanames.ora file after the data in the test1.out file.
Now that the desired data has been written to the test1.out file, how does it make its way onto the Web page? Take a close
look at the code in Listing 12.23. You should see the following:
<!--#include file="test1.out"-->
This will take the listing and format it into a Web page for display on your browser. Figure 12.7 shows the output of this
procedure.
To complete the picture, let’s take a look at Listing 12.25, which shows the HTML code generated to display the contents
of the tnsnames.ora file. Listing 12.26 shows the actual contents of this file.
<HTML>
<HEAD>
file:///F|/My%20Bookcase/Database/Oracle/Oracle%20Databases%20On%20The%20Web/ch12/423-430.html (5 of 7)4/03/2005 6:16:26
Oracle Databases on the Web:Using Java And LiveHTML With Oracle WebServer
Here, you can see that the spooled output listing from the C shell script has been tagged for HTML display. This should
complete the picture of how LiveHTML can be used to include Unix files and execute Unix scripts on a server.
Summary
Now that we have looked at the usage for Java and LiveHTML in a WebServer environment, we can move on to the
performance and tuning of the Oracle server. Regardless of how well you have tuned your WebServer engine, the bulk of
the application work will still be done within the Oracle database. With the Oracle database becoming your weakest link,
the following chapters are dedicated to improving the performance of the Oracle engine with an eye toward creating fast
and efficient WebServer applications.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 13
Using SQL*Net For WebServer Communication
In a WebServer application, it is unusual for all of the databases to be on the same host
as the WebServer engine. Rather, we expect to see Oracle databases distributed onto
other host computers and Oracle’s SQL*Net used as the backbone for
communications. Distributed Oracle systems enable load-balancing of the subsets of
an application, giving each subset of data its own dedicated CPU. In a fully distributed
Oracle environment, the WebServer exists as a standalone application on one server
while the Oracle databases exist on remote servers.
Whenever you have this type of distributed Oracle architecture, you must carefully
examine the connectivity issues, so WebServer developers will be able to process data
from all of the Oracle servers, regardless of their physical location. This requires a
good understanding of SQL*Net, database links, table replication techniques, and
distributed Oracle design. This chapter should give you a conceptual understanding of
the role of SQL*Net and how it fits into the overall WebServer architecture.
Because we have implemented data location transparency with SQL*Net, the end user
does not know or care what databases are interrogated to satisfy his request. In the
previous example of count(*) with location transparency, the end user has no interest
in any individual databases when servicing the request, defining it as a global
transaction. The transaction manager has the responsibility to query all of the
distributed INVENTORY tables and collect the counts from each table, merging them
into a single result set.
In Oracle with SQL*Net, creating database links to the remote database and assigning
a global synonym to the remote tables achieves location transparency. At the lowest
level, computers are identified by an Internet Protocol (IP) address, which gives the
computer a distinct number. An example would be 222.223.90.27. The IP address is
associated with a server name using a Unix file called hosts. Table 13.1 shows how
these items are associated within an Oracle environment.
The three files—hosts, oratab, and tnsnames.ora—provide Oracle with the necessary
information to uniquely identify each distributed database.
end users to connect to databases in physically separate networks. At the lowest level,
TNS communicates to other databases with message-level send/receive commands. In
the following example, omaha.com is the database link, and it connects to the
omaha_server TNS service using the oracle_user_profile user ID:
Now that we have defined the location name, we can include tables from any of the
omaha sites by qualifying the remote site name in the SQL query. In the following
example, we join the EMPLOYEE table in omaha with our local SKILLS table:
select EMPLOYEE.employee_name,
SKILLS.skills_date
from [email protected],
SKILLS
where
EMPLOYEE.emp_number = SKILLS.employee_number
order by skills_date
;
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select But how do we hide the fact that the EMPLOYEE table resides in omaha? To make the location
of this table transparent to the developer, the DBA may assign synonyms for the EMPLOYEE
table in omaha that would make the query appear to be a local table:
select EMPLOYEE.employee_name,
SKILLS.skills_date
from EMPLOYEE,
SKILLS
where
EMPLOYEE.emp_number = SKILLS.employee_number
order by skills_date
;
Note: It is important to understand which Oracle instances are servicing this request.
Obviously, the omaha instance is responsible for retrieving the EMPLOYEE rows, but it
is not so apparent that it’s the initiating instance’s job to perform the merge sort for the
join. The local instance will also be the server that will sort the result set by skills_date.
Therefore, if you are issuing this type of distributed request from a WebServer host, you
need to ensure that your local WebServer database has enough space in the temporary
tablespace and that the sort_area_size init.ora parameter is large enough to handle the
sorting operations.
Oracle stored procedures can also be defined to allow for location transparency. Because the exact
table name and TNS location is hidden inside the stored procedure, the developer who calls the
routine can access the remote table without any reference to its physical location. For example,
the following procedure could be defined to allow updates to the EMPLOYEE table in omaha:
add_employee("Rick Tytler");
Location transparency can be very useful for hiding the complexity of a distributed Oracle
system, but there is much more to the story.
Most WebServer developers recognize the need to organize and manage remote locations of
databases while providing location transparency to key developers. To Oracle, the term domain is
used to define each remote database. Domains are especially important in situations of horizontal
partitioning. Horizontal partitioning occurs when tables with identical names are kept in
numerous locations. Domains can be used within Oracle to establish a logical hierarchy of
physical locations for all of the databases that participate in the WebServer application. The
sample database shown in Figure 13.1 establishes a domain hierarchy for remote databases.
Each node in the network shown in Figure 13.1 assigns synonyms for all unique tables within the
distributed network. For duplicate table structures existing at many locations, abbreviated
domains can be created. Assume that both Japan and Ohio have an EMPLOYEE table, identical
in structure but containing different rows. We could assign Oracle synonyms as follows:
SQL*Net makes it easy to allow cross-database access, so the issue of intersystem connectivity
must be understood. In a distributed Oracle system, you may see any of the following types of
table partitioning:
One very common method of Oracle database distribution is to use horizontal partitioning, where
different rows exist at remote locations and SQL*Net makes the remote tables appear as a single
table. For example, employee service organizations commonly allow their remote sites to
maintain employee information and maintain a location-transparent access mode to every
employee, regardless of their physical location. Horizontal partitioning is achieved by taking a
subset of each remote site’s EMPLOYEE table and populating a master lookup table that is
accessible from any node in the distributed system (see Figure 13.2).
Figure 13.2 Horizontal data partitioning of a master lookup table for a distributed WebServer
application.
In a WebServer system, the Unix cron utility can be used to schedule a periodic refresh of the
master table. cron is short for chronological, and it’s the name of the Unix utility used to schedule
jobs. As such, cron is a time-dependent task activation utility that starts tasks at predetermined
dates and times. An SQL script would automatically extract employee_name from the remote site
and repopulate the master EMPLOYEE table, leaving the employee details at the remote site.
The Oracle SQL might look like this:
Once populated, the master lookup table can be accessed by any node and used to redirect the
database query to the appropriate remote database for employee detail (see Figure 13.3).
Because of dynamic substitution in SQL, a common application can be made to access any
employee in the federation, regardless of the location and without any coding changes. For a
complete description of these techniques, refer to the text Managing Distributed Databases by
Donald K. Burleson, published by Wiley-QED Publishing.
Now that we understand how to make each location transparent to the WebServer application,
let’s explore the internals of Oracle’s SQL*Net. SQL*Net is a powerful tool that allows many
different configurations. A good knowledge of SQL*Net and all of its possible configurations will
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
In its most basic form, SQL*Net is a software tool that enables a network of Oracle
clients and servers to communicate transparently on top of any underlying network
topology or protocol using SQL. Although SQL*Net is a robust and sophisticated tool,
you must appreciate the inherent complexity that goes along with the flexibility of
SQL*Net. Due to the sophisticated architecture of SQL*Net, it’s not trivial to install
SQL*Net on the WebServer or any of the remote servers. Because we are dealing with
a WebServer front end, it’s important to note that the WebServer host will be the
client, while the remote Oracle databases will be the servers.
For a general overview of the SQL*Net architecture, let’s begin by looking at the
control files for SQL*Net. In Unix systems, the following four files are necessary to
operate SQL*Net 2.0:
On some flavors of Unix, such as HP-UX, these files are located in the /etc directory.
For Solaris Unix, the .ora files are located in the /var/opt/ oracle directory.
In SQL*Net version 2.0, Oracle has added several important enhancements. Aside
from the badly needed bug fixes, SQL*Net now allows access to multiple
communities. A community is a group of computers that share a common
communications protocol (such as TCP/IP to LU6.2). In addition, the Oracle7 database
engine now allows for the creation of a multithreaded server (MTS) for servicing
incoming data requests. In an MTS, all communication to databases is handled through
a single dispatcher, rather than a separate process being spawned for each incoming
database connection, as is the case with SQL*Net version 1.0.
When upgrading from SQL*Net 1.0 to SQL*Net 2.0, you should be aware of subtle
differences between how the two versions handle communications. (See Figure 13.4.)
SQL*Net version 1.0 uses an orasrv component on the destination database to listen
for incoming requests, while SQL*Net 2.0 uses a process called tnslsnr (TNS listener).
In addition, SQL*Net 1.0 cannot use an MTS.
On the client side, the User Programmatic Interface (UPI) converts SQL to associated
parse, execute, and fetch statements. The UPI parses the SQL, opens the SQL cursor,
binds the client application, describes the contents of returned data fields, executes the
SQL, fetches the rows, and closes the cursor. Oracle attempts to minimize messages to
the server by combining UPI calls whenever possible. On the server side, the Oracle
Programmatic Interface (OPI) responds to all possible messages from the UPI and
returns requests. All of this work is done after the request has been spawned through
the Web Listener and the Web Request Broker. Hence, there are many intermediate
steps that a WebServer request must perform before actually retrieving the Oracle
data. To further complicate matters, no UPI exists for server-to-server communication.
Instead, a Network Programmatic Interface (NPI) resides at the initiating server, and
the responding server uses its OPI for the request.
SQL*Net supports network transparency so that the network structure may be changed
without affecting the SQL*Net application. Location transparency is achieved with
database links and synonyms.
Let’s trace a sample WebServer data request through SQL*Net. The following steps
are performed:
But wait, it gets even more complex. As each data request is processed by the
WebServer host, SQL*Net looks for the link name in the database link table
(DBA_DB_LINKS) and extracts the service name. The service name is then located
in the tnsnames.ora file, and the host name is extracted. Once again, we have a three-
stage process beginning with the link name referencing the service name, and then the
service name referencing the host name.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select In Unix environments, the host name is usually found in a host file (/etc/hosts), and the Internal
Protocol (IP) address is gathered. In the following example, omaha_server might translate into an
IP address of 143.32.142.3. The following four steps illustrate how SQL*Net takes a remote
request and translates it into the IP address of the destination database:
1. Issues a remote request, and checks the database link called omaha.
2. The database link gets the service name (omaha_server_d) using the link_name
(omaha).
3. tnsnames.ora gets the SID name (omaha_sid) using service name (omaha_server_d).
omaha_server_d = (description=(address=(protocol=tcp)
(host=bluegill)
(port=1521) (connect_data=(sid=omaha_sid) (server=dedicated)))
4. /etc/hosts gets the IP address (143.32.142.3) using the SID name (omaha_sid).
As you can see, this translation occurs in a multistage process. The tnsnames.ora file specifies the
name of the host containing the destination database. For Unix environments, this host name is
then looked up in the /etc/hosts file to get the IP address of the destination box.
Note that the service name is looked up in tnsnames.ora — if the service exists, the IP address is
found in the /etc/hosts file, and a communications request is sent to the destination IP address.
Both of the entries in this file connect to omaha, but omaha_server_d directs SQL*Net to spawn
a dedicated process, while omaha_server uses the multithreaded server component because a
shared server is specified.
Now that you have the tnsnames.ora and /etc/hosts files in place, you can include any tables from
the omaha sites by qualifying the remote site name in the SQL query.
Note that this query joins two tables at different locations, and the database link called omaha
determines how the Oracle connection will be established on the destination system. However,
regardless of how the connection is made to the destination, the user ID must have select privileges
against the EMPLOYEE table, or this query will fail.
Connections to remote databases can be made by specifying either the service names or connect
strings. For SQL*Net, connect strings use the full connection, specifying the protocol:server:
database. In the following example, the t: means a TCP/IP connection, host: is the name of the
remote processor, and database: is the name of the databases on the host processor. The format for
the two selections are:
Connect strings are stored in the DBA_DBLINKS table and are created with the create database
link command, as follows:
SQL*Net can establish database communications via three methods: remote connection, remote
request, or distributed request. A remote connection is the easiest way to make a database
connection. The sending database simply makes a request by specifying a table name suffixed by
@. SQL*Net takes it from there, seamlessly accessing the remote database and returning the data
to the initiating system. Communication is established by making a distributed request to a remote
database. Within Oracle, @ specifies the remote database name, but the functionality of the @
operator depends on where it’s used. Here’s an example:
sqlplus scott/tiger@omaha
count(*)
——————
162
In this request, scott is using SQL*Plus to connect to the omaha database, and @omaha is the
service name, as defined in the tnsnames.ora file. SQL*Net recognizes this as a remote connection
and determines the appropriate linkage to establish communications with omaha. Internally,
Oracle will check the tnsnames.ora file to ensure that omaha is a valid destination. However, there
is another way of connecting to omaha from the same database. This is called a remote request.
Following is an example of a remote request:
sqlplus scott/tiger
select count(*) from EMPLOYEE@omaha;
count(*)
———————
162
Unlike a remote connection made directly from SQL*Plus, the remote request has scott connecting
to the local copy of SQL*Plus to specify the remote table (in this case, EMPLOYEE@omaha).
For a remote request to work, a database link must define omaha. A database link is a connection
pathway to a remote database that specifies the service name of the remote database. Without the
database link, the following request would fail:
sqlplus jenny_burleson/secret_password
This error message results from the way Oracle defines the @ operator for remote connections.
When entering an Oracle service, such as SQL*Plus from the Unix command prompt, the @
operator will go directly
ITKnowledge
Please Select Let’s take a closer look at a database link. In this simple example, no mention is made of the user ID used to establish the
connection on the remote database. Because scott is the user connecting to SQL*Plus, scott will be the user ID when the
remote connection is established to the omaha database. Therefore, scott must have select privileges against the
EMPLOYEE table in omaha in skills for the query to work properly. scott’s privileges on the initiating Oracle database
have no bearing on the success of the query.
Note: If you are using the Oracle Names facility, you must be sure that your database service names are the same as the
global_databases_names and the domain init.ora parameter.
In cases where select security is not an issue, you can enhance the database link syntax to include a remote connect
description:
This way, all users who specify the omaha database link will connect as scott1 // and will have whatever privileges scott1 //
has on the omaha system. Once you establish a communications pathway to the remote database, it is often desirable to
implement location transparency. In relational databases such as Oracle, you can obtain location transparency by creating
database links to the remote database and then assigning a global synonym to the remote tables. The database link specifies a
link name and an SQL*Net service name. You can create database links with a location suffix that is associated with a host
name (in this example, omaha_server).
You can use database links to allow applications to point to other databases without altering the application code. For data
warehousing applications, you can replicate a table on another machine and establish links to enable the application to point
transparently to the new box containing the replicated table.
To see the links for a database, query the Oracle dictionary in the following manner:
Keep in mind that SQL*Net bypasses all operating system security settings when it connects to a database. All user accounts
identified externally (that is, without an Oracle password) will not be allowed in SQL*Net transactions unless the init.ora
parameter is changed. The identified externally clause (sometimes called OPS$) in Oracle version 6 allowed the operating
system to manage passwords, but because SQL*Net bypasses the operating system, impostor accounts could be created from
other platforms. For example, a Unix user running a PC-based Unix operating system such as Coherent could set their user
ID to anyone they desired, and then connect with SQL*Net to any remote database with all database privileges consistent
with the user ID. Consequently, Oracle now recommends that identified externally accounts be forbidden for distributed
connections.
It is interesting to note that Oracle will allow you to create accounts with an OPS$ prefix. Therefore, the operating system
can manage its passwords, while you also have passwords within Oracle. For example, assume the following user definition:
Assuming that scott has logged onto the operating system, scott could enter SQL*Plus either with or without a password, as
follows:
sqlplus /
sqlplus scott/tiger
This ability to connect directly to Oracle presents a confounding issue with password management. Because two sets of
passwords exist—one in the operating system and another in Oracle—you may need a third-party tool to keep the passwords
synchronized.
Each version of Oracle has its own listener process. For SQL*Net version 1.0, the listener process is called orasrv, and the
SQL*Net version 2.0 listener process is called tnslsnr. Using the Unix ps command, you can see the listener processes
running on your server, as shown in Listing 13.1.
ps -ef|grep ora
oracle 1201 1 80 Nov 13 0:02 /u00/oracle/product/7.3.2/bin/tnslsnr
LISTENER -inherit
oracle 934 1 3 Nov 13 0:00 orasrv
oracle 1443 1 83 Nov 13 0:32 /u00/oracle/product/7.3.2/bin/oraweb -C u00/dba/
oracle/app/orac
oracle 1231 1 80 Nov 13 0:02 /u00/oracle/product/7.3.2/bin/wrb2 16 4 /u00/dba/
oracle/app/orac
From Listing 13.1, we can see the SQL*Net listeners, WebServer listener, and Web Request Broker running on this server.
To see what the Oracle listeners are doing, Oracle provides a series of listener commands, which include:
There are three listeners that accept and activate these commands. The activation commands are as follows:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Therefore, if we wanted to check the status of the SQL*Net version 2.0 Listener, we could issue the command
lnsrctl stat. Listing 13.2 shows the output of the lsnrctl stat command.
Connecting to (ADDRESS=(PROTOCOL=TCP)(HOST=ram2)(PORT=1521))
STATUS of the LISTENER
————————————
Alias LISTENER
Version TNSLSNR for HPUX: Version 2.0.15.0.0 - Production
Start Date 29-AUG-94 13:50:16
Uptime 18 days 1 hr. 47 min. 45 sec
Trace Level off
Security OFF
Listener Parameter File /etc/listener.ora
Listener Log File /usr/oracle/network/log/listener.log
Services Summary...
dev7dba has 1 service handlers
ram2dba has 1 service handlers
The command completed successfully
Connecting to (ADDRESS=(PROTOCOL=TCP)(HOST=bluegill)(PORT=1521))
Services Summary...
ftdab000 has 4 service handlers
DISPATCHER established:1 refused:0 current:2 max:55 state:ready
D001 (machine: bluegill, pid: 4146)
(ADDRESS=(PROTOCOL=tcp)(DEV=5)(HOST=141.123.224.38)(PORT=1323))
DISPATCHER established:1 refused:0 current:2 max:55 state:ready
D000 (machine: bluegill, pid: 4145)
(ADDRESS=(PROTOCOL=tcp)(DEV=5)(HOST=141.123.224.38)(PORT=1321))
DISPATCHER established:0 refused:0 current:1 max:55 state:ready
D002 (machine: bluegill, pid: 4147)
(ADDRESS=(PROTOCOL=tcp)(DEV=5)(HOST=141.123.224.38)(PORT=1325))
DEDICATED SERVER established:0 refused:0
The command completed successfully
As a service request is intercepted by an Oracle server, the listener may direct the request via a dedicated
server, an MTS, or an existing process (also known as a prespawned shadow). The key is whether the
connection contacts the listener via a service name or bypasses the listener with the two_task connect string.
If the listener is contacted as part of the connection and the MTS parms are defined to init.ora, the client will
use the MTS.
There are five basic listener commands: reload, start, stop, status, and services. Based on the request, the
listener decides whether to dispatch a connection to a dedicated-server process (which it spawns) or to use the
MTS. The programmer has several options when deciding how Oracle will manage the process. Dedicated
requests can be specified by a version 1.0 connect string or by using a service name that specifies
server=dedicated in the tnsnames.ora file.
Listing 13.3 describes some of the utilities you can use to manage SQL*Net sessions effectively. You should
be aware that some of the examples in this section are operation system–independent and may not apply to
your environment.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
One of the problems with SQL*Net version 1.0 was that each incoming transaction was
spawned by the listener as a separate operating system task. With SQL*Net version 2.0,
Oracle now has a method for allowing the listener connection to dispatch numerous
subprocesses. With the MTS, all communications to a database are handled through a single
dispatcher instead of separate Unix process IDs (PIDs) on each database. This translates into
faster performance for most online tasks. Even local transactions will be directed through the
MTS, and you will no longer see a PID for your local task when you issue the Unix
command ps -ef|grep oracle.
However, be aware that the MTS is not a panacea, especially at times when you want to
invoke a dedicated process for certain WebServer connections. For a process that has little
idle time, such as an intensive table update with WebServer (and also Pro*C programs or I/O-
intensive SQL*Forms applications), you will get better performance if you bypass the MTS
and use a dedicated process connection. In general, the MTS offers benefits, such as reduced
memory use, fewer processes per user, and automatic load balancing.
Remember the following rules of thumb when initially starting the MTS:
• The MTS is governed by the init.ora parameters. If no MTS parms are present in
init.ora, the MTS is disabled.
• The MTS is used when the MTS parms are in the init.ora and requests are made by
service name (such as @my_database). In other words, you must retrieve the rowid
of all version 1.0 connect strings (such as t:unix1:my_database).
• Each user of the MTS requires 1 K of storage, so plan to increase your
shared_pool_size.
• The V$QUEUE and V$DISPATCHER system tables indicate whether the number
of MTS dispatchers is too low. Even though the number of dispatchers is specified in
the init.ora file, you can change it online in SQL*DBA with the alter system
command, as follows:
• If you encounter problems with the MTS, you can quickly regress to dedicated
servers by issuing an alter system command. The following command turns off the
MTS by setting the number of MTS servers to 0:
• In order to use OPS$, you must set two init.ora values to true (the default is false),
as follows:
remote_os_authent = true
remote_os_roles = true
• When both SQL*Net 1.0 and 2.0 are installed, the user may connect to the server
via a dedicated server or the MTS. However, you cannot stop and restart the listener
when connecting via the MTS. You must connect to SQL*DBA with a dedicated
server.
• In some cases, the instance must be bounced if the listener is stopped, or it will
restart in dedicated mode. Whenever an instance is to be bounced, stop the listener,
shut down the instance, restart the listener, and start up the instance. The listener reads
the MTS parameters only if it’s running before startup of the instance. Therefore,
bouncing the listener will disable the MTS.
The listener is a software program that runs on each remote node and “listens” for any
incoming database requests. When a request is detected, the listener may direct the request to
any of the following:
• Dedicated server
• Multithreaded server
• Existing process or prespawned shadow
Note that the configuration of an Oracle listener is a direct result of the parameters specified
in the startup deck for the Oracle database. This parameter file is called init.ora and will
contain the parameters used to define the multithreaded server and listener, as shown in
Listing 13.4.
#———————————-
# Multithreaded Server
#———————————-
MTS_DISPATCHERS = "tcp,3"
MTS_MAX_DISPATCHERS = 5
MTS_MAX_SERVERS = 20
#—————————————-
# Distributed systems options
#—————————————-
DISTRIBUTED_LOCK_TIMEOUT = 60
DISTRIBUTED_RECOVERY_CONNECTION_HOLD_TIME = 200
DISTRIBUTED_TRANSACTIONS = 6
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
In some cases, you may want your WebServer application to issue updates against two or more remote
databases in a single SQL command. When a distributed update (or delete) has finished processing,
SQL*Net will coordinate commit processing, which means that the entire transaction will roll back if any
portion of the transaction fails. The first phase of this process is to issue a prepare phase to each node,
followed by the commit, and then terminated by a forget phase.
If a distributed update is in the process of issuing the 2PC and a network connection breaks, Oracle will
place an entry in the DBA_2PC_PENDING table. The recovery background process (RECO) will then
roll back or commit the good node to match the state of the disconnected node to ensure consistency. You
can activate RECO via the alter system enable distributed recovery command.
The DBA_2PC_PENDING table contains an advise column that directs the database to either commit or
roll back the pending item. You can use the alter session advise syntax to direct the 2PC mechanism. For
example, to force the completion of an insert, you could enter the following:
When a 2PC transaction fails, you can query the DBA_2PC_PENDING table to check the state column.
You can enter SQL*DBA and use the Recover In-Doubt Transaction dialog box to force either a rollback
or a commit of the pending transaction. If you do this, the row will disappear from DBA_2PC_PENDING
after the transaction has been resolved. If you force the transaction the wrong way (for example, rollback
when other nodes committed), RECO will detect the problem, set the mixed column to yes, and the row
will remain in the DBA_2PC_PENDING table.
Internally, Oracle examines the init.ora parameters to determine the rank that the commit processing will
take. The commit_point_strength init.ora parameter determines which of the distributed databases is to
be the commit point site. In a distributed update, the database with the largest value of
commit_point_strength will be the commit point site. The commit point site is the database that must
successfully complete before the transaction is updated in the other databases. Conversely, if a transaction
fails at the commit point site, the entire transaction will be rolled back at all of the other databases. In
general, the commit point site should be the database that contains the most critical data. Listing 13.5
shows a script that identifies 2PC transactions that have failed to complete.
select local_tran_id,global_tran_id,state,mixed,advice
from dba_2pc_pending
skills by local_tran_id;
On systems running SQL*Net version 2.0, the following SQL*Plus script can be used to query the number
of dedicated and shared servers on the system. For example, Listing 13.6 shows an SQL*Plus script to
view all sessions.
Wed Sep 24
Page 1
ram2db Database
Sessions for SQL*Net
11 rows selected.
Summary
Now that we have reviewed the basics of distributed Oracle database management, you should have a good
idea of how a distributed Oracle database can be integrated for use by a WebServer application by using
database links and SQL*Net connections. While we can only gloss over the high points of SQL*Net in this
chapter, sophisticated tools such as SQL*Net 2.0 require a great deal of knowledge and skill to use
effectively. As systems continue to evolve into complex distributed networks, interdatabase
communications will continue to become more complex and require more sophisticated tools. Object-
orientation promises to make interdatabase communications simple, but the DBA in the trenches will
continue to struggle with implementing everyday distributed database communications.
In the following chapters, we will take a look at Oracle database design issues to ensure that the Oracle
database portion of the WebServer application does not become the bottleneck in the overall system.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Basic GO
Please Select
CHAPTER 14
Logical Design For WebServer Applications
There are many books containing tips on the effective design of Oracle systems, but
many of these texts are purely theoretical and fail to take into account the real-world
issues involved in designing a high-performance Oracle database. In this chapter, we’ll
take a real-world approach toward designing WebServer applications and discuss the
importance of system response time.
As we know, there are five basic types of data relationships that must be modeled
when designing any Oracle database:
• one-to-one
• one-to-many
• many-to-many
• recursive many-to-many
• “is a” (ISA)
The effective WebServer designer must be able to represent these five types of data
relationships in a sensible way, while ensuring acceptable Oracle database
performance. This chapter focuses on one-to-many and many-to-many relationships.
As the size of the database increases, data redundancy can become a major problem.
Today, many users create very large databases, many of which contain trillions of
bytes. For databases of this size, a single table can contain more than a billion rows,
and the introduction of a single new column to a table could represent thousands of
dollars in additional disk expense. Data redundancy is detrimental for two reasons.
First and foremost, duplicating the redundant material consumes disk storage space.
Second, updating redundant data requires extra processing. Redundant duplication of
very large and highly volatile data items can cause huge processing bottlenecks.
However, this does not imply that redundancy is always undesirable. Performance is
still an overriding factor in most systems. Proper control of redundant information
implies that redundant information may be introduced into any structure, as long as the
performance improvements outweigh the additional disk costs and update problems.
Since the first publication of Dr. E. F. Codd’s 1993 research paper, Providing OLAP
(Online Analytical Processing) to User-Analysts: An IT Mandate, database designers
have attempted to find an optimum way of structuring tables for low data redundancy.
Codd’s rules of normalization often guide designers to create logically correct table
structures with no redundancy, but many designers have found that performance
demands often dictate the introduction of duplicate table data.
This is especially true for distributed Oracle databases. Any node in a distributed
database may want to browse a list of customers from another node without
establishing a connection to it. In addition, the technological complexity inherent in
Oracle’s two-phase commit often necessitates the widespread replication of entire
tables or selected columns from tables. However, the distributed database designer
does not have free reign to introduce redundancy anywhere in the enterprise.
Redundancy always has a price tag, whether it is the cost of the disk storage or the cost
of maintaining a parallel update scheme. Figure 14.1 shows a strategy for analyzing
the consequences of data redundancy.
In Figure 14.1, a boundary line lies within a range between the size of a redundant data
item and the frequency in which the data item updates. The size of the data item relates
to the disk costs associated with storing the item, and the frequency of update is
associated with the cost of keeping the redundant data current, whether by replication
techniques or by two-phase commit updates. Because the relative costs are different
for each hardware configuration and for each application, this boundary may be quite
different depending on the type of application. The rapid decrease in disk storage costs
means that the size boundary is only important for very large-scale redundancy. A
large, frequently changing item (for example, street_address) is not a good candidate
for redundancy. But large static items (for example, service_history) or small,
frequently changing items (such as product_price) may be acceptable for redundancy.
Small static items (for example, gender) represent ideal candidates for redundant
duplication.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
One-To-Many Data Relationships
In Figure 14.2, we see that the structure is in pure Third Normal Form. Notice that the
CITY and STATE tables exist because each state has many cities and each city has
many customers. This model works for most transactions in an online transaction
processing (OLTP) system. However, this high degree of normalization would require
the joining of the CITY and STATE tables each time address information is
requested, forcing some SQL requests to perform very slowly.
Consider a query to display the state_bird for all orders that have been placed for
birdseed. This is a cumbersome query that requires the joining of six tables, as shown
in Listing 14.1.
select state_bird
from STATE, CITY, CUSTOMER, ORDER, QUANTITY, ITEM
where
item_name = 'BIRDSEED'
and
ITEM.item.nbr = QUANTITY.item.nbr
AND
QUANTITY.order_nbr = ORDER.order_nbr
AND
ORDER.cust_nbr = CUSTOMER.cust_nbr
AND
CUSTOMER.cust_city = CITY.cust_city
AND
CITY.state_name = STATE.state_name;
With Oracle and the rule-based optimizer, this type of complex join guarantees that at
least one table is read front to back using a full-table scan, and a full-table scan may
slow down even the best WebServer application. This is a shortcoming of Oracle’s
rule-based optimizer, because an SQL optimizer should generally avoid a full-table
scan whenever indexes are present (except, of course, when the table is very small).
This situation might be avoided by using Oracle hints with the cost-based optimizer to
determine the optimal path to this data. A hint is an extension of Oracle’s SQL that
directs the SQL optimizer to change its normal access path.
But what happens if you are designing a data warehouse and your goal is to simplify
the data structure by removing several of the one-to-many relationships? For example,
you may choose to eliminate the “one” side of a relationship by copying the data
columns into the “many” side of the relationship. This is a very common approach in
the design of denormalized STAR schemas for use by Oracle 7.3 data warehouses.
(We’ll talk more about STAR schemas later in this chapter.)
However, adding redundancy poses two issues. First, you need additional disk space
for the redundant item, and second, you need to provide a technique to update the
redundant item if it needs to be changed. In our example, one solution is to build a
table of columns that rolls the CITY and STATE tables into the CUSTOMER table.
Table 14.1 assumes that the STATE table contains 50 rows, the CITY table has 2,000
rows, and the CUSTOMER table has 10,000 rows.
From Table 14.1, you can see that the CITY and STATE tables can be removed
entirely for a total savings of 400,000 bytes (refer to Figure 14.3). What about the
cost_of_living field? If we choose to eliminate the CITY table, and duplicate
cost_of_living in every CUSTOMER table row, it would be necessary to visit each
and every CUSTOMER row—which means changing the cost of living 10,000 times.
Before this change, the following SQL was used to update each CITY table:
Using the same state_bird query as before, we see how it is simplified by removing
the extra tables, as follows:
select state_bird
from CUSTOMER, ORDER, QUANTITY, ITEM
where
item_name = 'BIRDSEED'
and
ITEM.item_nbr = QUANTITY.item_nbr
and
QUANTITY.order_nbr = ORDER.order_nbr
and
ORDER.cust_nbr = CUSTOMER.cust_nbr;
It is still necessary to join three tables, but this results in a much faster, simpler query
than the original six-way table join. You can carry this concept to the point where this
model is condensed into a single, highly redundant table.
When creating an E/R model, it is often tempting to look at the data model from a
purely logical perspective without any regard for the physical implications of the
model. The designer strives to recognize and establish all of the logical relationships in
the model while sometimes finding that the relationships are misleading. A
relationship can be misleading when the relationship actually exists, but the
application may have no need to reference this relationship. Consider the E/R model
for a university shown in Figure 14.4.
Consider the association of the hair_color attribute to the student entity. Does a many-
to-many data relationship really exist between hair_color and student? Many students
have blonde hair, and blonde hair is common to many students. Why not create a
many-to-many relationship between student and hair_color? The solution depends
upon whether any other non-key data items exist within the hair_color entity.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select If many other data items relating to hair color are present, then it is perfectly
appropriate to create another entity called hair_color. But in this case, even though a
many-to-many relationship exists between hair_color and student, hair_color is a
standalone data attribute, so it is unnecessary to create an additional data structure.
Another example is the zip_code attribute in the student entity. At first glance, it
appears that a violation of Third Normal Form (that is, a transitive dependency) has
occurred between city and zip_code. In other words, it appears that a zip_code is
paired with the city of residence for the student. If each city has many zip_codes,
while each zip_code refers only to one city, it makes sense to model this as a one-to-
many data relationship (see Figure 14.5). The presence of this data relationship
requires creating a separate entity called zip with attached student entities. However,
this is another case where the zip entity lacks key attributes, making it impractical to
create. In other words, zip_code has no associated data items. Creating a database
table with only one data column would be nonsense.
The example in Figure 14.5 demonstrates that it is not enough to group together like
items and then identify the data relationships. A practical test must be made regarding
the presence of no-key attributes within an entity class. If an entity has no attributes
(that is, the table has only one field), the presence of the entity is nothing more than an
index to the foreign key in the member entity. It can be removed from the E/R model.
This technique not only simplifies the number of entities, but it creates a better
environment for a client/server architecture. More data is logically grouped together,
resulting in less data access effort.
A student takes many courses, and each course has many students. This is a classic
many-to-many relationship that would require that we define a junction table between
the base entities to establish the foreign keys necessary to join the tables together. Note
that the junction table is called GRADE with the following contents:
Next, consider the question, In what context does a grade have meaning? Stating that
“The grade was A in CS-101” is insufficient, and stating that “Joe earned an A” makes
no sense. Only when both the student name and the course number are associated does
the grade column have meaning. Stating that “Joe earned an A in CS-101” makes
sense.
the same time, it is a component in a larger assembly. Or, a class at a university may
have many prerequisites, but, at the same time, it is a prerequisite for other classes.
Look closely at the COMPONENT example. Both the has_part and is_a_part fields
are foreign keys for the part_nbr field in the PART table. Therefore, the
COMPONENT table contains all key values except for the qty field, which tells how
many parts belong in an assembly. To understand how this works, look at the
following SQL code used to display all components in a Big_Meal:
select part_name
from PART, COMPONENT
where
has_part = 'BIG MEAL'
and
PART.part_nbr = COMPONENT.has_part;
This type of Oracle SQL query requires joining the table against itself. Unfortunately,
because all items are of the same type (namely, PART), no real substitute exists for
this type of data relationship, therefore the BOM relationship will most likely remain
popular in Oracle.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
One of the most popular uses for Oracle WebServer has been servicing the front-end requirements for
decision support systems and data warehouses. Oracle has announced that their Oracle Express multi-
dimensional component has now been Web enabled, but there is still a need to use Web pages for the display
(and data capture) of decision support information. One common use of WebServer is to allow end users to
display highly summarized Oracle data on Web pages, where they can use MS-Windows cut-and-paste
commands to extract data into spreadsheets for further analysis. Because the data can be gathered from a Web
page, developers do not need to write cumbersome data downloading routines, and end users can get data
from anywhere in the world.
The STAR schema design was first introduced by Dr. Ralph Kimball as an alternative database design for
data warehouses. The name STAR comes from the design that the completed schema creates, where a large
fact table resides at the center of the model surrounded by various reference tables, or points. The basic
principle behind the STAR query schema is the introduction of highly redundant data for high performance.
Returning to the customer-order E/R model in Figure 14.3, we see an illustration of a standard Third Normal
Form database used to represent the sales of items. Because redundant information is not an issue, salient data
(such as the total for an order) is computed from the items comprising the order. In this Third Normal Form
database, users need a list of line items to multiply the quantity ordered by the price for all items belonging in
order 123. An intermediate table called TEMP holds the result list, as shown in the following example:
Note: The STATE-CITY-CUSTOMER hierarchy in Figure 14.2 is very deliberate. To be truly in the
Third Normal Form, no redundant information is allowed. As such, a user’s seemingly simple query is
complex to the system. For example, the SQL calculating the sum of all orders for the Western region
looks very complex and involves the five-way table join, as follows:
where
QUANTITY.item_nbr = ITEM.item_nbr /* join QUANTITY and ITEM */
and
ITEM.cust_nbr = CUSTOMER.cust_nbr /* join ITEM and CUSTOMER */
and
CUSTOMER.city_name = CITY.city_name /* join CUSTOMER and CITY */
and
CITY.state_name = STATE.state_name /* join CITY and STATE */
and
STATE.region_name = 'WEST';
In reality, sufficient redundancy eliminates the CITY and STATE tables. The point is clear: A manager
analyzing a series of complete order totals requires a huge amount of realtime computation. This process
arrives at the basic tradeoff. For true freedom from redundant data, query time demands a price.
In practice, the Third Normal Form database generally evolves into a STAR schema as you create a fact table
to hold the quantity for each item sold (see Figure 14.9).
At first glance, it’s hard to believe this is the same data as the normalized database. The new fact table
contains one row for each item on each order, resulting in a tremendous amount of redundant key information
in the table. It should be obvious that the STAR query schema requires far more disk space than a Third
Normal Form database. Also, the STAR schema is most likely a read-only database because of the wide-
spread redundancy introduced into the model. Finally, the widespread redundancy makes updating difficult (if
not impossible) for the STAR schema. Notice the dimension tables around the fact table. Some of the
dimension tables contain data that is added to queries with joins. Other dimensions, such as the Region
dimension, contain no data. What purpose, then, does this STAR schema achieve with huge disk space
consumption and a read-only restriction?
Using the STAR schema in Figure 14.9, let’s formulate SQL queries for rapid retrieval of desired information.
For example, identifying the total cost for an order is simple, as seen in the following code:
It is clear that the new structure makes the realtime query faster and simpler. Consider the result if the goal is
to analyze information by aggregate values using this schema. Suppose that the manager needs the breakdown
of regional sales. The data by region is not available, but the FACT table supplies the answer. Obtaining the
sum of all orders for the Western region is now simple, as seen in the following code:
select sum(total_cost)
from FACT
where
region = 'WEST'
The merits of the STAR schema should now be apparent, but we need to note some other ways to represent
time-oriented data suitable for OLAP type systems, namely, the multidimensional database architecture, as
seen in Oracle Express.
Summary
It should now be clear to the reader how a proper design can be critical for good database performance. While
far from being an exhaustive description of all of the relational design techniques, this chapter has focused on
basic principles that will help to ensure that your WebServer database performs as quickly as possible.
Once a good logical model has been created, it is critical to translate the logical model into an Oracle
implementation capable of performing at optimal speed. Oracle involves many design issues, and in this
chapter we’ve taken a look at how some physical design models can be used to exploit client/server
performance.
We have come to believe that response time is one of the most critical factors to the success of any database.
Regardless of how well the system was analyzed or implemented—no matter how flashy the GUI
interface—if the system fails to deliver data in a timely fashion, the project is doomed. Now that we have
reviewed logical database design, let’s move on to the physical implementation of WebServer databases.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 15
Physical Oracle Design
When creating a WebServer application, you must pay careful attention to the
components that might affect system response time. These considerations include
WebServer’s interaction with the Internet, Web Listener, Web Request Broker, and
Oracle databases. Unfortunately, you have virtually no control over the Internet’s
speed and very little control over the Web Listener and Web Request Broker. Oracle’s
Web Listener and Web Request Broker have both been preoptimized by Oracle and
cannot be tuned by adjusting any of their parameters. However, you can control how
these components interact with your Oracle databases. More than other online
applications, special consideration must be given to Oracle databases. Database
transactions must be serviced efficiently to ensure that Web pages are sent to end users
quickly.
This chapter takes a look at the physical Oracle database design issues that can
influence the performance of your WebServer applications. The topics in this chapter
include the use of table replication with snapshots, referential integrity, index
placement, and Oracle’s parallel facilities. The overall focus is on the use of physical
database techniques for creating high-performance Oracle WebServer applications.
Without an effective physical design, no amount of tuning will significantly improve
performance. Hence, it is critical to any WebServer effort that you derive the optimal
performance from all of your Oracle database servers.
Oracle snapshots are used to create read-only copies of tables in other Oracle
databases. Table replication is a highly effective way to avoid time-consuming and
expensive cross-database joins of tables. As we know, an SQL join with a table at a
remote server will be far slower than a join with a local table. The network overhead
also increases as Oracle retrieves and transfers data across the network. The prudent
use of replicated tables can greatly improve the response time for WebServer
applications.
It’s interesting to note that the general attitude about data replication has shifted
dramatically in the past 10 years. In the 1980s, table replication was too expensive,
both in terms of disk costs and the processing costs to update redundant tables. Also,
academia believed that there was no substitute for the Third Normal Form database,
and students were taught Codd’s Rules of Normalization as if the rules were physical
laws of nature. Today, the practical realities of cheap disks and distributed processing
have made replication an inexpensive and viable alternative to expensive cross-
database joins.
Table replication has proven to be stable and has been so successful within Oracle
version 7 that Oracle version 7.3 is now introducing the concept of updatable
snapshots. Snapshot is the term used by Oracle to implement their table replication
strategy. However, table replication is not to be used indiscriminately, and the
following several guidelines exist for using replicated tables in a WebServer
application:
Despite any claims by Oracle to the contrary, only tables that meet the listed criteria
should be placed in snapshots. In practice, snapshots are not maintenance-free, and
many points of failure are possible—especially if the snapshot is created with the
refresh fast option. Problems can occur writing to the SNAPSHOT_LOG table, and
SQL*Net errors can cause failures of updates to transfer to the replicated tables.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
A snapshot is created on the destination system with the create snapshot SQL
command, and the remote table is immediately defined and populated from the master
table.
After a snapshot has been created, it may be refreshed periodically. There are two
types of refreshing in Oracle: complete and fast. A complete refresh can be done in
several ways, but most savvy Oracle developers drop and re-create the snapshots with
a Unix cron job to achieve full refreshes, especially if the table is small and easily re-
created. Optionally, tables can be refreshed with only the changes made to the master
table. This requires additional work on the slave database to create an Oracle refresh
process (in the init.ora) and the definition of a snapshot log on the master database (see
Figure 15.1).
Several steps need to be completed by the Oracle database administrator before your
Oracle system is ready to use snapshots. First, the DBA needs to run catsnap.sql,
which can be found in your $ORACLE_HOME/rdbms/admin directory. This script
will populate the Oracle dictionary with the necessary system tables to manage the
snapshots. The DBA also needs to run dbmssnap.sql, which can be found in the
$ORACLE_HOME/rdbms/admin directory. This script creates the stored procedures
that can be used to manipulate the snapshots.
The following parameters must also be added to the init.ora file for each Oracle
instance:
For snapshots that are small enough to be totally repopulated, it is recommended that
the following steps are followed to re-create the snapshot from scratch. Note that it is
possible to do a refresh complete or a refresh force rather than a cron job, but using
a cron is a simple way to guarantee that the replicated table will be fully repopulated.
To avoid the refresh fast option with a Unix cron, the following two steps are
required:
For snapshots on large tables, you may want to use the refresh fast option. To use
refresh fast, the following steps are required:
1. Destination system—Create the snapshot with the refresh fast option signed
on as user SYS. (Be sure to define a database link with connect to xxx
identified by zzz and ensure that user xxx has select privileges against the
master table.)
2. Master system—Create a snapshot log on each master table.
3. Bounce the destination system to begin the refreshes based on the interval
specified in the create snapshot.
Listing 15.1 shows an example of a snapshot that reads a table from an instance called
fairport.
CONNECT sys/xxxx;
DROP PUBLIC DATABASE LINK fairport;
CREATE PUBLIC DATABASE LINK fairport
CONNECT TO db_link IDENTIFIED BY db_pass USING 'fairport';
————————————————————————————
DROP SNAPSHOT my_replicated_table;
————————————————————————————
CREATE SNAPSHOT my_replicated_table
PCTFREE 10 PCTUSED 40
TABLESPACE ts2
STORAGE (initial 60k next 10k pctincrease 1)
REFRESH FAST
START WITH SYSDATE
NEXT (sysdate+1) + 3/24
AS SELECT * FROM ORACLE.my_master_table@fairport;
GRANT ALL ON my_replicated_table TO PUBLIC;
—******************************************************
— Add the appropriate synonyms for the snapshots...
—******************************************************
CONNECT /;
CREATE PUBLIC SYNONYM snap$_my_replicated_table FOR
ops$oracle.snap$_my_replicated_table;
In Listing 15.1, you can see that the my_replicated_table table is refreshed each
morning at 3:00 AM, and the read-only name snap$_my_replicated_table has been
replaced with synonym my_replicated_table. Following is an example of the
snapshot log syntax that needs to be run on the master database:
EXECUTE dbms_snapshot.refresh('office','f');
The snapshot log is a table that resides in the same database as the master table, which
can be seen in the dba_tables view as a table with the name MLOG
$_TABLENAME. In our example, the snapshot log would be called MLOG
$_EMPLOYEE.
Even with Oracle’s distributed features, it is still far faster to process a table on a local
server than it is to process a remote table across SQL*Net’s distributed
communication lines. As such, table replication is a very desirable technique for
improving processing speeds.
Several factors influence the decision about replicating tables. The foremost
considerations are the size of the replicated table and the volatility of the tables. Large,
highly active tables with many updates, deletes, and inserts will require a lot of system
resources to replicate and keep synchronized with the master table. Smaller, less active
tables would be ideal candidates for replication, because the creation and maintenance
of the replicated table would not consume a high amount of system resources.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Oracle’s snapshot facility is relatively mature and generally works as noted in the Oracle
documentation. However, the flexibility of the snapshot tool gives the developer many choices
concerning how the snapshot will be created and refreshed. You can refresh a replicated table in full, re-
create a snapshot at will, choose to periodically refresh a snapshot, and use database triggers to
propagate changes from a master table to a snapshot table. Although the choice of techniques depends
on the individual application, some general rules apply.
If a replicated table is small and relatively static, it is usually easier to drop and re-create the snapshot
than to use Oracle’s refresh complete option. A crontab file can be set up to invoke the dropping and
re-creation of a snapshot at a predetermined time each day—completely refreshing the entire table.
Another popular alternative to a snapshot is the use of Oracle’s distributed SQL to create a replicated
table directly on the slave database. In the following example, the New York database creates a local
table called EMP_NY, which contains New York employee information from the master employee
table at corporate headquarters:
Very large replicated tables consume too much time in dropping and re-creating a snapshot or using the
refresh complete option. For static tables, a snapshot log would not contain very many changes—we
could direct Oracle to propagate the changes to the replicated table at frequent intervals. Let’s take a
look at the different refresh intervals that can be specified for a snapshot. The following code tells
Oracle to apply the snapshot log to the replicated table every seven days:
refresh fast
start with sysdate
next sysdate+7
as select emp_nbr, emp_name from employee@hq where department = 'NY';
The next example code shows the command for a table to be refreshed each Tuesday at 6:00 AM:
For very static tables, you can specify refreshes to run quarterly. The following example refreshes a
table completely on the first Tuesday of each quarter:
For dynamic tables that require refreshing daily, you can specify that the table is refreshed at a
particular time each day. The following code refreshes a table every day, at 11:00 AM:
In addition to using the time range specified in the create snapshot syntax, you can also use Oracle
stored procedures to get the same results. If you run the dbmssnap.sql script, you can refresh a snapshot
by issuing the following command:
What about replicated tables that require instantaneous propagation? Oracle version 7.3 offers updatable
snapshots. Fortunately, users of previous releases of Oracle can also update snapshots by using database
triggers to simulate the realtime propagation of changes from a master table to replicated tables. In the
following example, an update trigger has been placed on the employee tables, and relevant changes will
be propagated to the New York branch:
Your next question might be, What can we do about rows deleted from the employee table? Using the
same technique, a delete trigger can be placed on the employee table to remove rows from the
replicated tables:
As we have seen, snapshot replication is very handy for taking a master table and copying it to a remote
location. But, what if we only want to replicate a portion of a table? Yes, Oracle provides a method for
excluding certain rows and columns from the replicated table. For example, let’s assume that you are
replicating a central employee table for use by your New York branch. However, you only want to
replicate employee records for those who work in the New York branch, and you want to exclude
confidential columns, such as the employees’ salaries. The snapshot would appear as follows:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Using Referential Integrity With Oracle
each dependent belongs to only one employee. The references constraint tells
Oracle at insert time that the value in DEPENDENT.emp_num must match
the EMPLOYEE.emp_num in the employee row, thereby ensuring that a
valid employee exists before the dependent row is added. At SQL delete time,
the references constraint can be used to ensure that an employee is not deleted
if rows still exist in the DEPENDENT table.
• Unique Constraint—This constraint is used to ensure that all column values
within a table never contain a duplicate entry.
Notice the distinction between unique and primary key. While both of these
constraints create a unique index, a table may contain only one primary key
constraint column—but it may have many unique constraints on other columns.
Referential integrity usually needs to be double coded: once for the database and again
within the application. For example, in a multipart SQL*Form, you may not become
aware of an RI violation until you are many pages into the form and your form
attempts to commit. In WebServer applications, you do not have the luxury of making
a lot of queries against the database, and you need to be careful to keep the Oracle
transactions as few as possible.
It is clear that enforcing this business rule in our new distributed environment is a real
challenge. While it is relatively simple to tell an Oracle system not to delete a row
from its CUSTOMER table if rows for that employee exist in the ORDER table, it is
not simple to enforce this rule when the CUSTOMER table resides in a Sybase
database and the ORDER table resides within Oracle. The solution is to remove the
database RI rules from each database, remembering to manually replicate the RI rules
using procedural code within the application. This essentially creates your own
customized RI within the application.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
Indexes And Oracle Performance
In Oracle, an index is used to speed up the time required to access table information.
Internally, Oracle indexes are B-tree data structures, in which each tree node may
contain many sets of key values and row IDs.
In general, Oracle indexes exist for the purpose of preventing full-table scans. Full-
table scans have two problems, the most important being the time lost in servicing a
request as each and every row of a table is read into Oracle’s buffer pool. The second
problem associated with full-table scans is that they cause performance degradation at
the system level. All other tasks on the system may have to incur additional I/O,
because the buffer block held by competing tasks will have been flushed by the full-
table scan. As blocks are flushed from the buffer pool, other tasks incur additional I/Os
to reread information that would have remained in the buffer pool if the full-table scan
had not been invoked.
In general, just about any Oracle table will benefit from the use of indexes. The only
exception to this rule would be a very small table that can be read in less than two
physical I/Os. Two physical I/Os are used as the guideline because Oracle needs to
perform at least one I/O to access the root node of the index tree and another I/O to
retrieve the requested data. For example, assume that a lookup table contains rows of
25 bytes each, and you have configured Oracle to use 4 K block sizes. Because each
data block would hold about 150 rows, using an index for up to 300 rows would not
make the processing any faster than a full-table scan.
If you plan to use the Oracle parallel query facility, all tables specified in the SQL
query must be optimized for a full-table scan. If an index exists, the cost-based
optimizer must be used with a hint to invalidate the index in order to use parallel
query. For the rule-based optimizer, indexes can be turned off by using an Oracle
One important concept in indexing is the selectivity, or the uniqueness, of the values in
a column. To be effective, an index column must have many unique values. Columns
that have only a few values (e.g., sex = m/f, status = y/n) would not be good
candidates for indexing. Similar to the index itself, the sparse distribution of values
would be less efficient than a full-table scan. To see the selectivity for a column,
compare the total number of rows in the table with the number of distinct values for
the column. For example:
Another concept used in indexing is called distribution, which refers to the frequency
that each unique value is distributed within the database. For example, we may have a
state_abbreviation column that contains 1 of 50 possible values. This would be
acceptable to use as an index column, provided that the state abbreviations are
uniformly distributed across the rows. However, if 90 percent of the values are for
New York, then the index will not be very effective. Oracle has addressed the index
data distribution issue with the analyze table command. When using Oracle’s cost-
based SQL optimizer, analyze table will look at both the selectivity and distribution
of the column values. If they are found to be out-of-bounds, Oracle may decide not to
use the index.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
Tuning Queries With Indexes
As a general rule, indexes will always increase the performance of a database query. In
situations where a query intends to sweep a table in the same sequence that the rows are
physically stored, the indexes in some tables may actually hinder performance. For
Oracle, indexes are recommended for two reasons: to speed the retrieval of a small set of
rows from a table and to presort result sets so that the SQL order by clause does not
cause an internal sort.
In order to use an index, the SQL optimizer must recognize that the column has a valid
value for index use. This is called a sargeable predicate, and it’s used to determine the
index access. Listing 15.2 shows some valid predicates, and Listing 15.3 shows invalid
predicates.
Whenever a transformation to a field value takes place, the Oracle database will not be
Some databases, such as DB2, will recognize a linear search and invoke a sequential
prefetch to look ahead, reading the next data block while the previous data block is being
fetched by the application. As a general rule, an SQL query that retrieves more than 15
percent of the table rows in a table will run faster if the optimizer chooses a full-table
scan rather than an index.
For example, assume that a student table has 1,000 rows, representing 900 undergraduate
students and 100 graduate students. A nonunique index has been built on the
student_level field that indicates underdgrad or grad. The same query will benefit
from different access methods, depending upon the value of the literal in the where
clause. The following query will retrieve 90 percent of the rows in the table and will run
faster with a full-table scan rather than an index:
This next query will only access 10 percent of the table rows and will run faster by using
the index on the student_level field:
Unfortunately, the Oracle database cannot predict in advance the number of rows that
will be returned from a query. Many SQL optimizers will invoke an index access even
though it may not always be the fastest access method.
To remedy this problem, some dialects of SQL allow the user to control the index access.
This is a gross violation of the declarative nature of theoretical SQL, in which the user
does not control access paths. But, in practice, these extensions can improve
performance. Oracle, for example, allows the concatenation of a null string to the field
name in the where clause to suppress index access. The previous query could be
rewritten in Oracle SQL to bypass the student_level index, as follows:
The concatenation (||) of a null string to the field tells the Oracle SQL optimizer to
bypass index processing for this field, instead of invoking a faster-running full-table scan.
This a very important point. While SQL optimizers are becoming more intelligent about
their databases, they still cannot understand the structure of the data and will not always
choose the best access path.
Concatenated Indexes
A concatenated index is an index created on multiple columns. This type of index can
greatly speed up queries where all of the index columns are specified in the queries’ SQL
where clauses. For example, assume the following index on the STUDENT table:
The following concatenated index could be used to speed up queries that reference both
student_level and major in the where clause:
However, some queries using only major or student_level will not be able to use this
concatenated index. In the following example, only the major field is referenced in the
query, and a concatenated index cannot be used to service the query:
In the following example, we see that student_level is the high-order index key, and the
index will be used because student_level is the high-order index key:
Because student_level is the first item in the index, the leading portion of the index can
be read, and the SQL optimizer will invoke an index scan. Why have we chosen to add
the last_name to the index, even though it is not referenced in the where clause?
Because Oracle will be able to service the request by reading only the index, and the
rows of the STUDENT table will never be accessed. Also, because the order by clause
asks to sort by last_name, Oracle will not need to perform a sort on this data.
The not (!) operator will cause an index to be bypassed, and the query “show all
undergrads who are not computer science majors” will cause a full-table scan:
Here, the not condition isn’t a sargeable predicate and will cause a full-table scan.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
While most commercial database products provide mechanisms for locking and
concurrency control, new issues emerge when using a relational database such as
Oracle (see Figure 15.3). This problem is especially prevalent when a single Oracle
task updates multiple remote servers, which is becoming increasingly common with
distributed Oracle systems. The real nightmare begins when the remote servers are of
differing architectures—for example, a distributed update to a relational and a network
database. In these cases, the concurrency control is generally turned off for each
database and is provided for inside the application program. After all, neither database
can be expected to manage the internals of the other database.
In addition to the technical issues, the popularity of client/server interfaces has also
changed how concurrency is handled. Many client/server systems disable their Oracle
database locking and rely upon procedural tricks to maintain data integrity at the
server level. Oracle is one of these products, and we’ll discuss how to avoid contention
by disabling Oracle locks.
Most programmers do not realize that database deadlocks occur frequently within
database indexes. It’s important to note that a select of a single row from a database
may cause more than one lock entry to be placed in the storage pool. When one row is
locked, all affected index rows will also be locked. In other words, the individual row
receives a lock, as well as each index node that contains the value for that row. If the
“last” entry in a sorted index is retrieved, the database will lock all index nodes that
reference the indexed value (in case the user changes that value). Many indexing
schemes always carry the high-order key in multiple index nodes, so an entire branch
of the index tree can be locked—all the way up to the root node of the index. While
each database’s indexing scheme is different, some relational database vendors
recommend that tables with ascending keys be loaded in descending order, so that the
rows are loaded from Z to A on an alphabetic key field. Oracle recommends dropping
indexes before large updates and re-creating the indexes after the rows have been
loaded into the table.
When an update or delete is issued against a row that participates in an index, the
database will attempt an exclusive lock on the row, which requires the task to check
for any shared locks held against the row as well as any index nodes that will be
affected. Many indexing algorithms allow for the index tree to dynamically change
shape, spawning new levels as items are added and condensing levels as items are
deleted.
One guideline for determining when to use an index involves examination of the SQL
issued against a table. In general, the SQL can be collected, and each value supplied in
each SQL where clause could be a candidate for inclusion in an index.
Keep in mind that indexes do much more than speed up an individual query. When
full-table scans are performed on a large Oracle table, the buffer pool begins to page
out blocks from other queries. This causes additional I/O for the entire database and
results in poor performance for all queries—not just the offending full-table scan.
Indexes are never a good idea for long descriptive columns. A column called
employee_description would be a poor choice for an index because of its length and
the inconsistency of the data within the column. If this column was 300 bytes, Oracle
select status
from EMPLOYEE
where
employee_last_name = 'burleson';
The following queries would bypass the index, causing a full-table scan:
select status
from EMPLOYEE
where
employee_last_name = lower('burleson');
select status
from EMPLOYEE
where
employee_last_name like 'burl%';
Unlike other relational databases, Oracle cannot physically load a table in key order.
Consequently, we can never guarantee that the rows in the table will be in any
particular physical order.
The use of an index can help whenever the SQL order by clause is used. For example,
even if there are no complex where conditions, the presence of a where clause will
assist the performance of the query. Consider the following SQL:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
In Oracle, some constraints will create an index on your behalf. For example, creating a primary
key constraint on the EMPLOYEE table for the emp_id will create an index on the field, and it is
not necessary to manually build an index (see Listing 15.4).
organization_name char(20)
constraint org_fk references ORG on delete restrict,
region_name char(2)
constraint state_check
check (region_name in ('north', south', 'east', 'west'))
);
Notice that you should always specify the location clause when declaring constraints. In the
previous example, had the emp_ukey constraint been defined without the storage clause, the index
would have been placed in whatever tablespace is specified by the table owner’s default tablespace,
with whatever default storage parameters are in effect for that tablespace.
Listing 15.4 shows some good examples of Oracle constraints. The first constraint is on the
emp_nbr column—the primary key. When you use Oracle’s RI to specify a primary key, Oracle
automatically builds a unique index on the column to ensure that no duplicate values are entered.
The second constraint is on the dept_name column of the DEPT table. This constraint tells Oracle
that it may not remove a department row if there are existing employee rows that reference that
department. The on delete cascade tells Oracle that when the department row is deleted, all
employee rows that reference that department will also be deleted.
The last RI constraint is called a check constraint. In a check constraint, Oracle verifies that a
column is one of the valid values before inserting a row, but it will not create an index on the
column.
When an SQL request is commonly issued using multiple columns, a concatenated or multicolumn
index can be used to improve performance. Oracle supports the use of multivalued indexes, but
there are some noteworthy limitations. Unlike other relational databases, Oracle requires that all
columns in the index are sorted in the same order, either ascending or descending. For example, if
we needed to index on employee_last_name ascending, followed immediately by gross_pay
descending, we would not be able to use a multivalued index.
Sometimes, two columns that have poor selectivity (i.e., columns having few unique values) can be
combined into an index that has better selectivity. For example, we could combine a status field
that has three values (good, neutral, and bad) with another column such as state_name (only 50
unique values), thereby creating a multivalued index that has far better selectivity than each column
would have if indexed separately. Also, in Oracle version 7.3, bitmapped indexes can be defined
for columns with poor selectivity, thereby improving SQL through put.
Another reason for creating concatenated indexes is to speed the execution of queries that reference
all of the values in an index. For example, consider the following query:
select employee_last_name,
employee_status,
employee_zip_code
from EMPLOYEE
order by employee_last_name;
on EMPLOYEE
(employee_last_name, employee_status, employee_zip_code) ascending;
If this query were to be issued against the employee table, Oracle would never need to access any
rows in the base table! All of the key values are contained in the index, and the high-order key
(employee_last_name) is in the order by clause. Oracle can scan the index, retrieving the data
without ever touching the base table.
With the assistance of this feature, the savvy Oracle developer can add columns to the end of the
concatenated index so that the base table is never touched. For example, if the previous query also
returned the value of the employee_address column, this column could be added to the
concatenated index, dramatically improving performance.
• Use a composite index whenever two or more values are used in the SQL where the
clause and the operators are joined by and.
• Place the columns in the where clause in the same order as in the index, with data items
added at the end of the index.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
It is interesting to note that the fastest execution for an individual task may not always
be the best choice. For example, consider the following query against an employee
table:
select employee_name
from EMPLOYEE
where
credit_rating = 'poor'
and
amount_due > 1000
and
state = 'iowa'
and
job_description like lower('%computer%');
Here, you can see a query where a full-table scan would be the most efficient
processing method. Because of the complex conditions and the use of Oracle
extensions in the SQL, it might be faster to perform a full-table scan. However, the
fast execution of this task may be done at the expense of other tasks on the system as
the buffer pool becomes flushed.
In general, the type of optimizer will determine how indexes are used. As we know,
the Oracle optimizer can run as either rule-based or cost-based. As a general rule,
Oracle is intelligent enough to use an index if it exists, but there are exceptions to this
rule. The most notable exception is the n-way join with a complex where clause. The
rule-based optimizer will get confused and invoke a full-table scan on at least one of
the tables, even if the appropriate foreign key indexes exist for all of the tables. The
only remedy to this problem is to use the cost-based optimizer, which involves
analyzing statistics for each table.
You should also remember that Oracle will only use an index when the index column
is specified in its “pure” form. The use of the substr, upper, lower, and other
functions will invalidate an index. However, there are a few tricks to help you get
around this obstacle. Consider the following two equivalent SQL queries:
The second query, by virtue of the fact that it does not alter the index column, would
be able to use an index on the total_purchases column.
Before tackling this subject, a distinction needs to be made between multitasking and
multiprocessing. Multitasking refers to the ability of a software package to manage
multiple concurrent processes, thereby allowing simultaneous processing. Although
OS/2 and Windows NT are good examples of this technology, multitasking can be
found within all midrange and mainframe databases. Multiprocessing refers to the use
of multiple CPUs within a distributed environment where a master program directs
parallel operations against numerous machines. Two levels of multiprocessing are
possible. The first is the hardware level, where arrays of CPUs are offered. The second
is the software level, where a single CPU can be partitioned into separate logical
processors. The Prism software on the IBM mainframe environment is an example of
multiprocessing technology.
One of the greatest problems with implementing parallel processing systems is the
identification of parallelism. Parallelism refers to the ability of a computer system to
perform processing on many data sources in the same instant. Traditionally, database
applications were linear in nature. Today’s systems have many opportunities for
parallel processing.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select A review of the past 30 years makes it clear that tremendous improvements have been
made in the speed of processors. At the same time, the prices of processors have
continued to decline. However, this trend cannot continue forever. The physical nature
of silicon processors has been pushed to its limit and is now reaching a diminishing
point of return. In order to continue to enjoy increases in performance, either silicon
needs to be replaced as a medium or new ways need to be devised to exploit
parallelism in processing.
Parallelism is an issue of scale. Where a linear process may solve a problem in 1 hour,
a parallel system with 60 processors should be able to solve the problem in 1 minute,
as demonstrated in Figure 15.5. In some instances, this statement would be analogous
to the statement that one woman takes nine months to have a baby, so nine women
should be able to produce a baby in one month. Speed can only be improved in
situations where parallel processing is appropriate, which excludes traditional linear
systems where one process may not begin until the preceding one ends.
Other facets to parallel processing can be extremely valuable. A query against a very
large database can be dramatically improved if the data is partitioned. For example, if
a query against a text database takes one minute to scan a terabyte, then partitioning
the data and processing into 60 pieces would result in a retrieval time of one second.
Another key issue is the balancing of the CPU processing with the I/O processing. In a
traditional data processing environment, the systems are not computationally intensive,
and most of the elapsed time is spent waiting on I/O. However, this does not
automatically exclude business systems from taking advantage of multiprocessing.
With Oracle version 7.2, some powerful new features have been introduced to allow
parallel processes to be used against the Oracle database. These features include:
Please note that the new features of Oracle versions 7.2 and 7.3 will not be activated
unless the following init.ora parameter has been used:
COMPATIBILITY=7.3.0.0.0
Also, note that it is not necessary to have parallel processors (SMP or MPP) in order to
use and benefit from parallel processing. Even on the same processor, multiple
processes can be used to speed up queries. Oracle parallel query options can be used
with any SQL select statements—the only restriction being that the query performs a
full-table scan on the target table.
Parallel queries are most useful in distributed databases where a single logical table
has been partitioned into smaller tables at each remote node (see Figure 15.6). For
example, an employee table ordered by employee name may be partitioned into an
employee table at each remote database, such that you have a phoenix_employee, a
los_angeles_employee, and so on. This approach is very common with distributed
databases, where local autonomy of processing is important. However, what about the
needs of those in corporate headquarters? How can they query all of these remote
tables as a single unit and treat the logical employee table as a single entity?
While this splitting of a table according to a key value violates normalization theory, it
can dramatically improve performance for individual queries. For large queries that
span many logical tables, the isolated tables can be easily reassembled using Oracle’s
parallel query facility, as follows:
Note: The @ references refer to SQL*Net service names for the remote hosts.
We can now query the all_employee view as if it were a single database table, and
Oracle parallel query will automatically recognize the union all parameter, firing off
simultaneous queries against each of the three base tables. It’s important to note that
the distributed database manager will direct each query to be processed at the remote
location, while the query manager waits until each remote node has returned its result
set. The following query will assemble the requested data from the three tables in
parallel, with each query optimized separately:
select employee_name
from ALL_EMPLOYEE
where
total_purchases > 5000;
The result set from each subquery is then merged by the query manager.
Summary
Now that you understand the logical and physical database design issues that influence
WebServer’s performance, let’s take a look at the performance and tuning issues that
arise when creating a WebServer database. Let’s also look at how the tuning of SQL
can help WebServer’s performance. We’ll do just that, in upcoming chapters.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
CHAPTER 16
Database Performance And Tuning
There are several factors that influence the performance of a WebServer application.
While most of the factors are within the control of Oracle developers, some issues,
such as Internet communications, are beyond the control of the Oracle developer.
Consequently, we can only address performance and tuning of WebServer applications
from the time a URL request is intercepted by the Web Listener until the completed
request has been serviced and returned to the client. During this period, the following
steps occur:
Response time with the Oracle WebServer is a function of the interaction between
numerous components. The following components are listed in order of their impact
on WebServer performance and speed:
We have no control over the speed of the Internet, but we do have some control over
the Oracle components. Let’s take a look at some of the performance and tuning issues
involved with the last two components.
The Web Request Broker accepts connections from the Web Listener. These requests
are in the form of URLs. When the WRB first receives a request, it interrogates the
URL to determine the type of object being requested. The request could be for an
Oracle stored procedure, a Java routine, or any routine that has been defined with a
socket. The determination of the type of object being requested is a function of the
pathname in the URL. The internal meaning of pathnames is governed by the
WebServer configuration. For example, the WebServer may be configured so that
URL requests beginning with /oraproc are passed to the PL/SQL agent and URL
requests beginning with /java are passed to the Java interpreter.
Interacting with a PL/SQL agent is generally much easier than interacting with Oracle
using LiveHTML or Java. In addition, the PL/SQL agent is much faster than it was in
WebServer version 1.0. This is due to a change in the architecture, whereby each
instance of the PL/SQL agent stays connected to Oracle between database requests.
Continuous connection does not mean that a run-unit connection is maintained with
Oracle. Rather, it means that a communication connection to Oracle has been
established, but no database connection has been made via SQL*Net. As you know,
when someone establishes a connection to SQL*Plus, you can see the connection by
selecting the V$SESSION view within Oracle. This is not the case with WebServer,
because the PL/SQL agent only connects to Oracle during the servicing of the request.
The servicing of a PL/SQL request consists of the following steps:
Because each HTTP request initiates a new SQL*Net session, Oracle is technically
logging off and reestablishing an SQL*Net session each time a URL request is made.
However, this process happens quickly because the Oracle server connection is
maintained between URL requests.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Oracle Stored Procedures
As objects such as stored procedures and triggers become more popular, more
application code will move away from external programs and into the database engine.
Oracle has been encouraging this approach in anticipation of the object-oriented
features of Oracle8. We have even more reasons for using stored procedures with
WebServer applications because stored procedures are the method used for all PL/SQL
interfaces with Oracle. However, Oracle DBAs must be aware of the increased
memory demands associated with stored procedures. DBAs must plan carefully for the
increased memory requirements when processing logic within databases.
Today, most Oracle databases have only a small amount of code in stored
procedures—but this is rapidly changing. WebServer requirements aside, many
compelling benefits can be derived by placing all Oracle SQL inside stored
procedures. These benefits include:
• Better performance—Stored procedures are loaded once into the SGA and
remain there unless they become paged out. Subsequent executions of the
stored procedure are far faster than external code.
• Coupling of data with behavior—Relational tables can be coupled with the
behaviors associated with them by using naming conventions. For example, if
all behaviors associated with the EMPLOYEE table are prefixed with the table
name (i.e., EMPLOYEE.hire, EMPLOYEE.give_raise), then the data
dictionary can be queried to list all behaviors associated with a table (for
instance, select * from dba_objects where owner = ‘EMPLOYEE’), and
One of the foremost reasons why stored procedures and triggers function faster than
traditional code is related to Oracle System Global Area (SGA). After a procedure has
been loaded into the SGA, it will remain in the library cache until it’s paged out of
memory. Items are paged out of memory based on a least-recently-used algorithm.
Once loaded into the RAM memory of the shared pool, the procedure will execute
very quickly. The trick is to prevent pool-thrashing during the period when many
procedures are competing for a limited amount of library cache within the shared pool
memory. Thrashing is the condition where stored procedures are flushed out of the
library cache to make room for other stored procedures.
When tuning Oracle, two init.ora parameters emerge as more important than all of the
other parameters combined. These are the db_block_buffers and the
shared_pool_size parameters. These two parameters define the size of the in-memory
region that Oracle consumes on startup and determines the amount of storage available
to cache data blocks, SQL, and stored procedures.
end employee;
Here we have encapsulated all employee “behaviors” into a single package that will be
added into Oracle’s data dictionary. If we force our programmers to use stored
procedures, the SQL moves out of the external programs and into the database,
reducing the application programs into nothing more than a series of calls to Oracle
stored procedures.
As systems evolve and the majority of process code resides in stored procedures,
Oracle’s shared pool becomes very important. The shared pool consists of the
following subpools:
• Dictionary cache
• Library cache
• Shared SQL areas
• Private SQL area (these exist during cursor open/cursor close)
• persistent area
• runtime area
Click Here!
Click Here!
ITKnowledge
To prevent paging, packages can be marked as nonswappable, which tells the database that after their initial
load they must always remain in memory. This is called pinning or memory fencing. Oracle provides a
procedure called dbms_shared_pool.keep to pin a package. Packages can be unpinned with
dbms_shared_pool.unkeep.
Note: Only packages can be pinned. Stored procedures cannot be pinned unless they are placed into a
package.
The choice of whether to pin a package in memory is a function of the size of the object and the frequency of
its use. Very large packages that are called frequently might benefit from pinning, but any difference may go
unnoticed because the frequent calls to the procedure have kept it loaded into memory. Therefore, because the
object never pages out, the pinning has no effect. Also, the way procedures are grouped into packages may
have some influence. Some Oracle DBAs identify high-impact procedures and group them into a single
package, which is pinned in the library cache.
In an ideal world, the shared_pool parameter of the init.ora should be large enough to accept every package,
stored procedure, and trigger that may be used by an application. However, reality dictates that the shared
pool cannot grow indefinitely, and wise choices must be made in terms of which packages are pinned and
which are excluded from the pinning routine.
Because of their frequent usage, Oracle recommends that the standard, dbms_standard, dbms_utility,
dbms_describe, and dbms_output packages always be pinned in the shared pool. To illustrate how pinning
works, the following snippet demonstrates how a stored procedure called sys.standard can be pinned:
connect internal;
@/usr/oracle/rdbms/admin/dbmspool.sql
execute dbms_shared_pool.keep('sys.standard');
A stored procedure can be written to pin all of the recommended Oracle packages into the shared pool.
EXECUTE dbms_shared_pool.keep('DBMS_ALERT');
EXECUTE dbms_shared_pool.keep('DBMS_DDL');
EXECUTE dbms_shared_pool.keep('DBMS_DESCRIBE');
EXECUTE dbms_shared_pool.keep('DBMS_LOCK');
EXECUTE dbms_shared_pool.keep('DBMS_OUTPUT');
EXECUTE dbms_shared_pool.keep('DBMS_PIPE');
EXECUTE dbms_shared_pool.keep('DBMS_SESSION');
EXECUTE dbms_shared_pool.keep('DBMS_SHARED_POOL');
EXECUTE dbms_shared_pool.keep('DBMS_STANDARD');
EXECUTE dbms_shared_pool.keep('DBMS_UTILITY');
EXECUTE dbms_shared_pool.keep('STANDARD');
While this pinning routine ensures that a package stays pinned while the Oracle instance is running, you may
also want to ensure that a package gets pinned each time the Oracle instance is started. Users of Oracle for
Unix may want to add code to the /etc/rc file to ensure that the packages are repinned after each database
startup. The rc file is generally maintained by the Unix system administrator, and this process guarantees that
all packages are repinned with each bounce of the box. A pinning script might look like this:
The Oracle DBA must also remember to run pin.sql whenever restarting the Oracle database. This is done by
reissuing the pin command from inside svrmgrl immediately after the database has been restarted.
How do we identify frequently accessed packages? The Oracle alert logs do not provide this information, and
other methods must be found for sampling package usage. Listing 16.1 shows a handy script illustrating
pinned packages in the SGA. This procedure could be run periodically and piped into a shell script that would
maintain counts of the number of times each package has been called.
rem memory.sql
Display used SGA memory for triggers, packages, and procedures
SQL> @memory
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select You can determine the number of times a nonpinned stored procedure has been swapped out of memory and
required to reload. To effectively measure memory, two methods are recommended. The first recommended
method is to regularly run the estat-bstat utility (usually located in ~/rdbms/admin/utlbstat.sql and utlestat.sql) to
measure SGA consumption over a period of time. Another handy method would be writing a snapdump utility to
interrogate the SGA and note any exceptional information relating to the library cache. This would include the
following measurements:
Also, be aware that the relevant parameter, shared_pool_size, is used for other objects besides stored procedures.
This means that one parameter fits all, and Oracle offers no method for isolating the amount of storage allocated to
any subset of the shared pool.
Here is a sample report for gathering information relating to shared_pool_size. Let’s say you see that your data
dictionary hit ratio is above 95 percent and your library cache miss ratio is very low. You also notice that there are
over 125,000 reloads in the SQL area namespace. At this point, you may want to increase the shared_pool_size.
When running this type of report, always remember that statistics are gathered from startup and the numbers may
be skewed. For example, on a system that has been running for six months, the data dictionary hit ratio will be a
running average over six months. Consequently, data from the V$ structures is meaningless if you want to
measure today’s statistics.
Some Oracle DBAs will run utlbstat.sql, wait a short period, and then run utlestat.sql. This sequence produces a
report called report.txt, where values can be extracted. One alternative is shown in Listing 16.3, which shows short
customized statistics from the V$ tables in Oracle.
=========================
DATA DICT HIT RATIO
=========================
(should be higher than 90 else increase shared_pool_size in init.ora)
Data Dict. Gets Data Dict. cache misses DATA DICT CACHE HIT RATIO
41,750,549 407,609 99
=========================
LIBRARY CACHE MISS RATIO
=========================
(If > 1 then increase the shared_pool_size in init.ora)
=========================
LIBRARY CACHE SECTION
=========================
hit ratio should be > 70, and pin ratio > 70 ...
Let’s take a look at the SQL*Plus script (shown in Listing 16.4) that generated Listing 16.3.
PROMPT
PROMPT
PROMPT =========================
PROMPT DATA DICT HIT RATIO
PROMPT =========================
PROMPT (should be higher than 90 else increase shared_pool_size in init.ora)
PROMPT
PROMPT
PROMPT =========================
PROMPT LIBRARY CACHE MISS RATIO
PROMPT =========================
PROMPT (If > 1 then increase the shared_pool_size in init.ora)
PROMPT
COLUMN "LIBRARY CACHE MISS RATIO" FORMAT 99.9999
COLUMN "executions" FORMAT 999,999,999
COLUMN "Cache misses while executing" format 999,999,999
SELECT sum(pins) "executions", sum(reloads) "Cache misses while executing",
(((sum(reloads)/sum(pins)))) "LIBRARY CACHE MISS RATIO"
FROM v$librarycache;
PROMPT
PROMPT =========================
PROMPT LIBRARY CACHE SECTION
PROMPT =========================
PROMPT hit ratio should be > 70, and pin ratio > 70 ...
PROMPT
Just as the wisdom of the 1980s dictated that data should be centralized, the 1990s have begun an era where SQL
is also centralized and managed. With the centralization of SQL, many previously impossible tasks have become
trivial. For example:
As memory becomes less expensive, it will eventually become desirable to have all of the application’s SQL and
code loaded into the Oracle library cache, where the code will be available quickly for execution by any external
applications, regardless of platform or host language. The most compelling reasons for putting all SQL within
packages are portability and code management. If all applications become “SQL-less,” with calls to stored
procedures, then entire applications can be ported to other platforms without altering a single line of the
application code.
As the cost of memory drops, 500 MB Oracle regions will not be uncommon. Until that time, however, DBAs
must carefully consider the ramifications of pinning a package in the SGA.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Oracle Triggers
Many database systems now support the use of triggers that can be fired at specific events. The
insertion, modification, or deletion of a record may fire a trigger; or a business event, such as
place_order, may initiate a trigger. Oracle Corporation claims that the design of their triggers
closely follows the ANSI/ISO SQL3 draft standard (ANSI X3H6), but Oracle triggers are more
robust in functionality than the ANSI standard. Triggers are defined at the schema level of the
system, and will fire whenever an SQL select, update, delete, or insert command is issued.
Remember that a trigger is always associated with a single DML event.
The choice of when to use a trigger and when to use a stored procedure can have a profound impact
on the performance of the system. In general, triggers are used when additional processing is
required as a row is inserted into a table. For example, assume that whenever a customer row is
added, the system is required to look for the customer in the BAD_CREDIT table. If the customer
appears in the BAD_CREDIT table, then its shipping_status column is set to COD. In this case, a
trigger on insert of customer can fire the PL/SQL procedure to do the necessary lookup and set the
shipping_status field to its appropriate value.
Oracle triggers have the ability to call procedures, and a trigger may include SQL statements, thus
providing the ability to nest SQL statements. Oracle triggers are stored as procedures that may be
parameterized and used to simulate object-oriented behavior. For example, assume that we want to
perform a behavior called check_total_inventory whenever an item is added to an order. (See
Figure 16.1.)
Triggers can also be combined to handle multiple events, such as the reordering of an item when
the quantity-on-hand falls below a predefined level, as follows:
Oracle Hashing
Oracle7 now supports the concept of hash clusters. A hash cluster is a construct that works with
Oracle clusters and uses the hashkeys command to allow fast access to the primary key for the
cluster, thereby reducing I/O for your WebServer application. To reduce I/O, Oracle relies on a
hashing algorithm, which takes a symbolic key and converts it into a row ID (rowid). The hashing
function ensures that the cluster key is retrieved in a single I/O, which is faster than reading
multiple blocks from an index tree. Because a hashing algorithm always produces the same key
each time it reads an input value, duplicate keys have to be avoided. In Oracle, these collisions
result when the values of hashkeys are less than the maximum number of cluster key values. For
example, if a hash cluster uses the cust_nbr field as the key, and we know that there will be 50,000
unique cust_nbr values, then we must be sure that the value of hashkeys is set to at least 50,000.
Also, you should always round up your value for hashkeys to the next highest prime number.
Following is an example of a hash cluster:
The size parameter is usually set to the average row size for the table. Oracle recommends using a
hash cluster when the following are true:
• Use hash clusters to store tables commonly accessed by where clauses that specify
equalities.
• Only use hash clusters when you can afford to keep plenty of free space on each database
block for updates. This value is set by the pctfree statement in the create table parameter.
• Only use hash clusters if you are absolutely sure that you will not need to create a new,
larger cluster at a later time.
• Do not use a hash cluster if your table is commonly accessed by full-table scans,
especially if a great deal of extra space from future growth has been allocated to the hash
cluster. In a full-table scan, Oracle will read all blocks of the hash cluster, regardless of
whether they contain any data rows.
• Do not use a hash cluster if any of the hash cluster keys are frequently modified.
Changing the value of a hash key causes the hashing algorithm to generate a new location,
and the database will migrate the cluster to a new database block if the key value is
changed. This is a very time-consuming operation.
Keep in mind that the total size of the index columns must fit inside a single Oracle block. If the
index contains too many long values, additional I/O will be required and updates and inserts will
cause serious performance problems. Note the sample hashing routine shown in Figure 16.2.
The database designer may choose to make the buffer blocks large to minimize I/O if the
application clusters record on a database page. If a customer record is only 100 bytes, we will not
gain by retrieving 32,000 bytes in order to get the 100 bytes that we need. However, if we cluster
the orders physically near the customer (on the same database page), and if I/O usually proceeds
from customer to order, then we will not need further I/O to retrieve orders for the customer.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Please Select
Oracle Clusters
We need to note one important issue: While a cluster will tremendously improve
performance in one direction, queries in the other direction will suffer. For example,
consider the many-to-many relationship between customers and orders. We have the
junction table, ORDER_LINE, at the intersection of this many-to-many relationship
and we need to decide which owner, ORDER or ITEM, will be the anchor for our
cluster. If we commonly traverse from ORDER to ITEM (e.g., displaying an order
form), it would make sense to cluster the ORDER_LINE records on the same
database block as their ORDER owner. If, on the other hand, we commonly traversed
from ITEM to ORDER (e.g., requesting the details for all orders containing widgets),
we would cluster the ORDER_LINE rows near their ITEM owner. If we cluster on
the ORDER owner, database queries that display order forms will be very fast, while
queries in the other direction will have to do additional I/O.
One of the most exciting performance features of Oracle version 7.3 and above is the
ability to partition an SQL query into subqueries and dedicate separate processors to
concurrently service each subquery. At this time, parallel query is useful only for
queries that perform full-table scans on long tables, but the performance improvements
can be dramatic. Here’s how it works.
Instead of having a single query server manage the I/O against a table, parallel query
allows the Oracle query server to dedicate many processors to acess the data,
simultaneously, as shown in Figure 16.4.
To be most effective, the table should be partitioned onto separate disk devices, such
that each process can do I/O against its segment of the table without interfering with
the other simultaneous query processes. However, the client/server environment of the
1990s relies on RAID or a logical volume manager (LVM), which scrambles data files
across disk packs in order to balance the I/O load. Consequently, full utilization of
parallel query involves striping a table across numerous data files, each on a separate
device.
Even if your system uses RAID or LVM, some performance gains are still available
with parallel query. In addition to using multiple processes to retrieve the table, the
query manager will also dedicate numerous processes to simultaneously sort the result
set. (See Figure 16.5.)
Parallel query works best with symmetric multiprocessor (SMP) boxes, which have
more than one internal CPU. Also, it is important to configure the system to maximize
the I/O bandwidth, either through disk striping or high-speed channels. Because of the
parallel sorting feature, it is also a good idea to beef up the memory of the processor.
While sorting is no substitute for using a presorted index, the parallel query manager
will service requests far faster than a single process. The data retrieval will not be
significantly faster, though, because all of the retrieval processes will be competing for
a channel on the same disk. Each sort process has its own sort area (as determined by
the sort_area_size init.ora parameter), which speeds along the sorting of the result set.
In addition to full-table scans and sorting, the parallel query option also allows parallel
processing for merged joins and nested loops.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
ITKnowledge
Please Select Invoking the parallel query option requires all indexing to be bypassed. And, most importantly, the execution plan
for the query specifies a full-table scan. If the output of the explain plan does not indicate a full-table scan, the
query can be forced to ignore the index by using query hints.
The number of processors dedicated to service an SQL request is ultimately determined by the Oracle query
manager, but the programmer can specify the upper limit on the number of simultaneous processes. When using
the cost-based optimizer, the parallel hint can be embedded into the SQL to specify the number of processes. For
example:
If you are using SMP with many CPUs, you can issue a parallel request and leave it up to each Oracle instance to
use their default degree of parallelism, as follows:
• sort_area_size—The higher the value, the more memory available for individual sorts on each parallel
process. Note that the sort_area_size parameter allocates memory for every query on the system that
invokes a sort. For example, if a single query needs more memory and you increase the sort_area_size, all
Oracle tasks will allocate the new amount of sort area, regardless of whether they will use all of the space.
• parallel_min_servers—The minimum number of query servers active on the instance. System resources
are involved in starting a query server, so having the query server started and waiting for requests will
speed up processing. Note that if the actual number of required servers is less than the value of
parallel_min_servers, the idle query servers will be consuming unnecessary overhead, and the value
should be decreased.
• parallel_max_servers—The maximum number of query servers allowed on the instance. This parameter
will prevent Oracle from starting so many query servers that the instance is unable to service all of them
properly.
To see how many parallel query servers are busy at any given time, the following query can be issued against the v
$pq_sysstat table:
STATISTIC VALUE
Servers Busy 30
In this case, we see that 30 parallel servers are busy. Do not be misled by this number. Parallel query servers are
constantly accepting work or returning to idle status, so it is a good idea to issue the query many times over a one
hour period. Only then will you have a realistic measure of how many parallel query servers are being used.
Summary
Now that we have covered the some of the tricks that can be used within Oracle to speed up WebServer queries,
let’s take a look at the broader Oracle picture and explore how Oracle tuning can help WebServer at the system
level. In the next chapter, we’ll explore how Oracle memory (SGA) can be tuned so that you’ll achieve maximum
performance from your WebServer data requests.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 17
Tuning Oracle SQL
Up until now, you’ve been reading about the physical Oracle database issues involved
when creating a WebServer application; now let’s take a look at how Oracle’s SQL
can be tuned to ensure optimal performance from WebServer. While several books
have been devoted to the efficient use of Oracle SQL, only a handful of general rules
and guidelines are effective in guaranteeing optimal performance from Oracle
databases. This chapter focuses on the basic techniques for quickly achieving the
maximum SQL performance with the least amount of effort. Topics in this chapter
include:
SQL is a declarative language, so you can write a query many ways. And while each
query might return identical results, the execution time can vary dramatically. To
illustrate this concept, let’s consider a small employee table with 100 rows and an
index on sex and hiredate. Let’s say you issue the following query to retrieve all
female employees who have been hired within the last 90 days. The query uses
Oracle’s rule-based optimizer, as follows:
select emp_name
from EMPLOYEE
where
sex = 'F'
and
hiredate between sysdate-90 and sysdate;
Because the table has only 100 rows, the most efficient way to service this request
would be to use a full-table scan. However, Oracle will walk the index that exists,
performing dozens of extra I/Os as it reads the index tree to access the rows in the
table. This simplistic example serves to illustrate the concept that the execution time of
SQL is heavily dependent on the way a query is stated, as well as the internal index
structures within Oracle.
It’s true that each dialect of SQL is different, but general rules apply that can be used
to keep database queries running efficiently. And while these guidelines are no
substitute for the SQL explain plan facility, they can reduce the chances that a
database query will consume large amounts of system resources.
The first step is to look at the relative costs for each type of SQL access. Oracle has
published the cost list shown in Table 17.1 that describes the relative cost of each type
of SQL access.
As you can see, the fastest way to retrieve a row is by knowing its row ID. A row ID
(called a rowid in Oracle) is the number of the database block followed by the
displacement, or position, of the row on the block. For example, 1221:3 refers to the
third row on a page, on block number 1221. Many experienced Oracle programmers
capture the rowid for a row if they plan to re-retrieve it. In Oracle, rowid is a valid
column statement, such that you can select the rowid along with your data in a single
statement, such as:
Inside a WebServer application, PL/SQL storage arrays can be defined to hold rowid
values. For details, see Chapter 8, WebServer’s OWA Utilities.
When creating WebServer applications, keep in mind that the most expensive SQL
statement is one that invokes a full-table scan. As you may know, a full-table scan is
acceptable for small tables, but it can wreak havoc on an entire Oracle instance when a
full-table scan is invoked against a large table. Therefore, more than any other SQL
tuning technique, avoiding large-table full-table scans is a primary consideration. With
proper tuning of Oracle SQL, full-table scans can usually be avoided by using indexes
and index hints.
What about queries that need to read every row of a table? While a full-table scan may
be the fastest for an individual query where every row in the table must be read (i.e.,
using sum, avg, or queries with many complex where conditions), the full-table scan
is done at the expense of other SQL on the system. As a large-table full-table scan
reads rows into memory, buffer pages containing rows from other queries will be
flushed from the buffer, and Oracle will need to re-retrieve these rows. So, the
question is, do you tune an individual query for performance, or do you tune the
database as a whole? Generally speaking, we cannot allow a single query to achieve
good response time at the expense of all other tasks on the database.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
General Tips For Efficient SQL
Fortunately, some general rules are available for writing efficient SQL in Oracle. These
rules may seem simplistic, but diligently following them will relieve more than half of your
SQL tuning problems.
null string to the index column name (e.g., name||‘’), or add zero to a numeric
column name (e.g., salary+0).
• If your query will return more than 20 percent of the rows in the table, use a full-
table scan rather than an index scan.
• Always use table aliases when referencing columns.
Historically, queries pose a common problem with SQL. Simple queries can be written in
many different ways, each variant of the query producing the same result but with widely
different access methods and query speeds.
For example, a simple query such as “What students received an A last semester?” can be
written in three ways, as shown in Listings 17.1, 17.2, and 17.3, each returning an identical
result.
select *
from STUDENT, REGISTRATION
where
STUDENT.student_id = REGISTRATION.student_id
and
REGISTRATION.grade = 'A';
select *
from STUDENT
where
student_id =
(select student_id
from REGISTRATION
where
grade = 'A'
);
select *
from STUDENT
where
0 <
(select count(*)
from REGISTRATION
where
grade = 'A'
and
student_id = STUDENT.student_id
);
Each of these queries will return identical results, but the access path that the queries take
through the Oracle database varies greatly.
The following discussion will review the basic components of an SQL query, showing how
to optimize a query for remote execution. It is important to note that several steps are
required to understand how SQL is used in a distributed database. Distributed SQL queries
function in the same way as queries within a single database, with the exception that cross-
database joins and updates may utilize indexes that reside on different databases.
Regardless, a basic understanding of the behavior of SQL can lead to dramatic performance
improvements.
Because SQL is a declarative language, it is not immediately apparent how an SQL query is
being serviced. Whether or not Oracle is using an index, performing a full-table scan, or
performing a merge sort, is hidden from view. Fortunately, tools exist within Oracle’s
implementation of SQL that allow the access path to be interrogated.
To see the output of an explain plan, you must first create a plan table to store the output
from the explain. Oracle provides a script in $ORACLE_HOME/rdbms/admin with a script
called utlxplan.sql. Execute utlxplan.sql, and create a public synonym for the
PLAN_TABLE, as follows:
sqlplus>@utlxplan
table created.
sqlplus > create public synonym PLAN_TABLE for SYS.PLAN_TABLE;
synonym created.
Oracle uses the explain utility by taking the SQL statement as input, running the SQL
optimizer, and then sending the access path information into a PLAN_TABLE, which can
then be interrogated to see the access methods. Listing 17.4 runs a query against a sales
database to get the sum of costs for a particular month.
detcost.pac1 in ('N33','192','195','201','BAI',
'P51','Q27','180','181','183','184','186','188',
'198','204','207','209','211')
group by 'T'||costsnet.terr_code,
This syntax is piped into the SQL optimizer, which will analyze the query and store the plan
information in a row in the plan table identified by RUN1. Please note that the query will
not execute; it will only create the internal access information in the plan table. The plan
table contains the following fields:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select Now that the PLAN_TABLE has been created and populated, you may interrogate it to see your
output by running the following query:
SQL>@list_explain_plan
OPERATION
———————————————————————————————————
OPTIONS OBJECT_NAME POSITION
————————————— ——————————————— ————————————
SELECT STATEMENT
SORT GROUP BY 1
CONCATENATION
1
NESTED LOOPS
1
TABLE ACCESS FULL COSTSNET 1
NESTED LOOPS
From this output, you can see the dreaded table access full on the COSTSNET table. To diagnose
the reason, return to the SQL and look for any COSTSNET columns in the where clause. There you
can see that the COSTSNET column called mgc is being used as a join column in the query,
indicating that an index is necessary on COSTSNET.mgc to alleviate the full-table scan.
While the plan table is useful for determining the access path to the data, it doesn’t tell the whole
story. The configuration of the data is also a consideration. While the SQL optimizer is aware of the
number of rows in each table (the cardinality) and the presence of indexes on fields, the SQL
optimizer is not aware of data distribution factors, such as the number of expected rows returned
from each query component.
The other tool used with the plan table is an SQL trace facility. Most database management systems
provide a trace facility that shows the resources consumed within each query component. The trace
table will show the number of I/Os required to perform the SQL, as well as the processor time for
each query component.
Some other relational databases, such as DB2, allow the DBA to specify the physical sequence for
storing the rows. Generally, this sequence will correspond to the column value most commonly used
when the table is read sequentially by an application. If a customer table is frequently accessed in
customer ID order, then the rows should be physically stored in customer ID sequence. The explain
plan output will display many database access methods. The major access techniques include:
• and-equal—Indicates that tables are being joined and that Oracle will be able to use the
values from the indexes to join the rows.
• concatenation—Indicates an SQL union operation.
• counting—Indicates the use of the SQL count function.
• filter—Indicates that the where clause is removing unwanted rows from the result set.
• first row—Indicates that a cursor has been declared for the query.
• for update—Indicates that returned rows were write locked (usually by using the
select…for update of…).
• index (unique)—Indicates that an index was scanned for a value specified in the where
clause.
• index (range scan)—Indicates that a numeric index was scanned for a range of values
(usually with the between, less_than, or greater_than specified).
• intersection—Indicates a solution set from two joined tables.
• merge join—Indicates that two result sets were used to resolve the query.
• nested loops—Indicates that the last operation will be performed n times, once for each
preceding operation. For example, below the index (unique), these operations will be
performed for each row returned by table access (full): nested loops, table access (full) of
‘customer’, and index (unique) of sy_01_idx.
• projection—Indicates that only certain columns from a selected row are to be returned.
• sort—Indicates a sort, either into memory or the TEMP tablespace.
• table access (rowid)—Indicates a row access by rowid that is very fast.
• table access (full)—Indicates a full-table scan and is usually cause for concern unless the
Database statistics packages can be made to capture this information, but they tend to be very
resource intensive. Turning on SQL trace statistics for a very short period of time during processing
is a good practice to follow and enables you to gather a representative sample of the SQL access.
The prudent use of temporary tables can dramatically improve WebServer performance. Consider
the following example. You want to identify all users who exist within Oracle, but have not been
granted a role. You could formulate the following query:
This query runs in 18 seconds. Now, you could rewrite the same query to utilize temporary tables, as
follows:
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Tuning With The Rule-Based Optimizer
In Oracle’s rule-based optimizer, the ordering of the table names in the from clause
determines the driving table. The driving table is important because it is retrieved first,
and the rows from the second table are then merged into the result set from the first
table. Therefore, it is essential that the second table returns the least amount of rows
based on the where clause. This is not always the table with the least amount of rows
(i.e., the smallest cardinality).
In this example, a total select from the EMP_TABLE should specify the New York
table first because London has the least amount of returned rows. The SQL should
appear as follows:
select *
from emp@new_york, emp@london;
If the SQL specifies a where condition to include only Department 100, the order of
table names should be reversed, as follows:
select *
from emp@london, emp@new_york
where
DEPT = 100;
It’s not always known what table will return the least amount of rows, so procedural
code could be used to interrogate the tables and specify the tables in their proper order.
This type of SQL generation can be very useful for ensuring optimal database
performance, as shown in Listing 17.6.
As you probably know, Oracle version 7 offers two methods of tuning SQL. If you are
running version 7.2 or above, you can use the cost-based optimizer; releases of Oracle
7.1 and below require the rule-based optimizer. With the rule-based optimizer, the
indexing of tables and order of clauses within an SQL statement control the access
path. The cost-based optimizer automatically determines the most efficient execution
path, and the programmer is given hints that can be added to the query to alter the
access path. The cost-based optimizer or the rule-based optimizer is set in the init.ora
file when the DBA sets the optimizer_mode to rule, choose, first_rows, or all_rows.
Beware of using the choose option. When you give Oracle the ability to choose the
optimizer mode, Oracle will favor the cost-based approach if any of the tables in the
query contains statistics. (Statistics are created with the analyze table command.) For
example, if a three-table join is specified in choose mode and statistics exist for one of
the three tables, Oracle will decide to use the cost-based optimizer and will issue an
analyze table estimate statistics at runtime. This will dramatically slow down the
query.
The optimizer option (rule versus cost) can be controlled at the database level or at the
program level. Prior to version 7.0.16, the cost-based analyzer had significant
problems, and Oracle recommended the use of the rule-based optimizer.
Here are some tips for effective use of Oracle’s rule-based optimizer:
• Try changing the order of the tables listed in the from clause. Page 1915 in
Oracle RDBMS Database Administrator’s Guide states, “Joins should be
driven from tables returning fewer rows rather than tables returning more
rows.” In other words, the table that returns the fewest rows should be listed
last. This usually means that the table with the most rows is listed first. If the
tables in the statement have indexes, the driving table is determined by the
indexes. One Oracle developer recently slashed processing time in half by
changing the order of the tables in the from clause. Another developer had a
process shift from running for 12 hours to completing in 30 minutes by
changing the from clause.
• Try changing the order of the statements in the where clause. Here’s the
idea: Assume that an SQL query contains an if statement with several boolean
expressions separated by ands. Oracle parses the SQL from the bottom of the
SQL statement in reverse order. Therefore, the most restrictive boolean
expression should be on the bottom. For example, consider the following
query:
select last_name
from STUDENT
where
eye_color = 'BLUE'
and
national_origin = 'SWEDEN';
Here, the number of students from Sweden is assumed to be smaller than the
number of students with blue eyes. To further confound matters, if an SQL
statement contains a compound if separated by ors, the rule-based optimizer
parses from the top of the where clause. Therefore, the most restrictive clause
should be the first boolean item in the if statement.
• Analyze the existence/nonexistence of indexes; understand your data. Again,
unlike the cost-based optimizer, the rule-based optimizer only recognizes the
existence of indexes and does not know about the selectivity or the distribution
of the index column. Consequently, use care when creating indexes, especially
when using rule-based optimization. Consider all programs that use a field in a
where clause of a select. A field should only be indexed when a very small
subset (less than 10 percent) of the data will be returned.
• Check to see if the target table is fragmented. For example, a table could be
fragmented if it constantly has a large number of rows inserted and deleted.
This is especially true in pctfree because the table has been set to a low
number. Regular compression of the table with Oracle’s export/import utility
will restore the table row and remove fragmentation.
• Always run questionable SQL through explain plan to examine the access
path.
• Understand which “query paths” are the fastest. For example, accessing a
table by rowid is the fastest access method available where a full-table scan is
17 out of 18 for the ranking of query paths. (Reference Table 17.1 for the
complete list of relative costs.)
• Avoid joins that use database links into Oracle version 6 tables.
• Make effective use of arrays. Array processing significantly reduces database
I/O. Consider the following example. A table has 1,000 rows to be selected.
The records are manipulated and then updated in the database. Without using
array processing, the database receives 1,000 reads and 1,000 updates. With
array processing (assuming an array size of 100), the database receives 10 reads
(1,000/100) and 10 updates. According to Oracle, increasing the array size to
more than 100 has little benefit.
Beware of an Oracle rule-based “feature” whereby a join of numerous large tables will
always result in a full-table scan on one of the tables, even if all of the tables have
indexes and the join could be achieved with an index scan. Of course, full-table scans
are costly, and SQL hints can be used to force the query to use the indexes. You can
use hints with the rule-based optimizer.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Using Hints With The Cost-Based Optimizer
Here is a summary of the most common hints that can be added to SQL:
table.
• use_merge—Requests a sort-merge operation.
Remember, the cost-based optimizer will only be as accurate as the statistics computed
from the tables. The DBA will need to create a periodic cron job for statistics. This job
will re-estimate statistics for tables that are volatile and change columns frequently.
While a full analyze table xxx estimate statistics will interrogate every row of the table,
a faster method can be used by issuing analyze table estimate statistics sample nn
rows. By taking a sample of the rows within the table, the statistics generation will run
much faster. Keep in mind that one of the things the analyze command reviews is the
selectivity and distribution of values within an index. As such, care should be taken to
sample at least 100 rows from each table.
Here is a test that created a set of three tables—DEPT, DEPT1, and DEPT2—each with
an index on deptno and set optimizer_goal as rule in the init.ora. Listing 17.7 shows
the results of the query.
Listing 17.8 shows the previous query’s results without any hints.
If a hint was added for the DEPT2 index, the full-table scan would be on DEPT1, and so
on.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Tuning PL/SQL
Procedure Language/SQL is the standard procedural language for WebServer applications. PL/
SQL is also commonly used within Oracle’s SQL*Forms application framework. But the re-
emergence of PL/SQL’s popularity for non-SQL*Forms applications can be attributed to the
benefits of using Oracle stored procedures—which must be written with PL/SQL. It is Oracle’s
stored procedures that make the htp utilities possible for WebServer implementation. PL/SQL
offers the standard language constructs, including looping, if statements, assignment statements,
and error handling.
There are several problems with PL/SQL, each of which warrants special attention. PL/SQL
offers two types of SQL cursors: the explicit cursor and the implicit cursor. Explicit cursors are
manually declared in the PL/SQL, as follows:
DECLARE
CURSOR C1 IS
select last_name
from customer
where
cust_id = 1234;
However, it’s possible to issue the SQL statement directly in PL/SQL without specifying the
cursor name. When this happens, Oracle opens an implicit cursor to handle the request. Implicit
cursors create a tremendous burden for Oracle, as the implicit cursor must always reissue a fetch
command to ensure that only a single row is returned by the query. This will double the amount
of fetch statements for the query. The moral is simple: Always declare all cursors in your PL/
SQL.
PL/SQL allows certain types of correlated subqueries to run much faster than traditional Oracle
SQL queries. This is a critical issue with WebServer, because it may be much faster to embed all
Oracle SQL in PL/SQL rather than embedding the SQL in Perl or Java.
To illustrate why WebServer may run faster with PL/SQL than with Perl or Java SQL, consider a
situation where a bank maintains a general ledger table and a transaction table. At the end of the
banking day, the check transaction table is applied to the GENERAL_LEDGER table, making
the requisite deductions from the account_balance column. Let’s assume that the
GENERAL_LEDGER table contains 100,000 rows and 5,000 daily checks need to be
processed.
A traditional SQL query (shown in Listing 17.9) used to accomplish the updating of
account_balance would involve a correlated subquery. This is the type of SQL that you might
embed into a Perl or Java script for a WebServer application.
update general_ledger
set account_balance = account_balance -
(select check_amount from transaction
where
transaction.account_number = general_ledger.account_number)
where
exists
(select 'x' from transaction
where
transaction.account_number = general_ledger.account_number);
When Oracle detects a correlated subquery, Oracle will execute the subquery first, and then apply
the query result to the entire outer query. In this case, the inner query will execute 5,000 times,
and the outer query will be executed once for each row returned from the inner query. This is
called a Cartesian product and has always been a problem for this type of query.
Now, consider the identical query written in PL/SQL, as shown in Listing 17.10.
DECLARE
CURSOR c1 is
select account_number,
check_amount
from transaction;
keep_account_number number;
keep_check_amount number;
BEGIN
OPEN C1;
LOOP
fetch C1 into keep_account_number, keep check_amount;
exit when C1%NOTFOUND;
update general_ledger
set account_balance = account_balance - keep_check_amount
where account_number = keep_account_number;
END LOOP;
END;
Here you can see that each check amount is retrieved in a separate transaction and fetched into
cursor C1. For each check_amount, the balance is applied to the GENERAL_LEDGER row,
one at a time.
Summary
Now that you’ve reviewed Oracle database tuning for WebServer, let’s take a look into the future
to get an idea how the nature will be changing. As you may know, the next major release of
Oracle (version 8) will have object-oriented features, and the WebServer developer will benefit
from understanding how these changes to the Oracle architecture will affect the Oracle
WebServer product.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
CHAPTER 18
The Future Of Database Management
While Oracle WebServer is considered cutting-edge technology today, it will only be
a few short years before the technology again shifts direction. The introduction of
Oracle version 8, the concept of a “universal” database server, and the advances in
hardware technology are combining to present an exciting future for Oracle
applications. Many new terms are being used to describe future database
systems—knowledgebases, intelligent databases, neural databases, and database
machines are but a few. Oracle version 8 is just the beginning.
Oracle Version 8
In general, the Oracle8 engine is remarkably similar to the relational engine found in
Oracle 7.3, but with major extensions to the relational architecture. It is interesting to
note that Oracle has not discarded the idea of creating a “universal” database engine.
Oracle is calling Oracle8 the “Oracle Universal Server,” adding text and
multidimensional and object capabilities to the relational engine. The most exciting
enhancements involve the introduction of Sedona, the incorporation of the Oracle
Express MDDB, and the “object layer” that will be tightly coupled with the relational
engine.
Oracle Sedona
Due to the secrecy around the development of Oracle8, many Oracle professionals
assumed that Sedona was the code name for Oracle8. However, Sedona is actually an
extension to Oracle8. Sedona has been billed as a universal object manager, and it
appears that its basic function is to act as an object consolidator. Sedona will allow for
Oracle methods to be indexed and quickly located across many databases and
platforms. Sedona achieves this by placing an object wrapper around Oracle objects so
that they can be accessed by other distributed systems. While the details are sketchy,
Sedona will incorporate many of the features of an Object Request Broker (ORB),
with a metadata dictionary for the distributed management of objects. With Sedona,
object classes may be registered in a central repository so that they will be available
for use transparently across the enterprise. Oracle has made the interface specifications
for Sedona available to third-party software vendors, hoping that vendors will create
application products utilizing Sedona.
Oracle ConText
A text searching option called Oracle ConText has also been added to the relational
engine of Oracle8. Oracle ConText allows thematic word searching capabilities
against Oracle’s relational database. Although the ConText option indexes on each
word within the text, the real power of the text retrieval system is located in the front-
end software. While this represents a major improvement over Oracle Book (which is
now obsolete), it remains to be seen how ConText will compete in the marketplace as
a text search engine. There are two fundamental ways to measure the accuracy of text
retrieval:
Together, precision and recall represent the overall accuracy of a text retrieval system.
Natural language is a phrase frequently heard in conjunction with concept-based
searching, and morphology is a term commonly used by text databases to simulate
natural language query. Morphology recognizes basic units of meaning and parts of
speech. To understand morphology, consider the phrase “Please write to Mr. Wright
right now.” To the human ear, all of the words sound identical; the meaning of the
words can be determined only by the context of the sentence. From the initial review,
it is still unclear how well Oracle ConText will be able to compete with the other more
established text engines such as ConQuest, Fulcrum, and Folio.
Oracle Express
Unlike Oracle 7.3, where the Express multidimensional database was installed
independently of Oracle, the Express product has been incorporated into the Oracle8
kernel. This implies yet another change for Oracle DBAs, who must now manage both
the relational and multidimensional components of Oracle. Oracle Express will be
offered for NT and PC, as well as Unix platforms. The basic reporting functions of
Unlike the Express product developed by IRI, Oracle Express has been enhanced so
that it does not require data to be preloaded into its internal data structures. This
enhancement enables Express to read relational data directly from relational Oracle
databases, dynamically transforming and aggregating the data for multidimensional
presentation. This means that Express will now compete against other relational back-
end products, such as Holos and MetaCube.
The object-oriented approach borrows heavily from C++ and Smalltalk. Both
languages allow for the storing of behaviors with the data, such that data and business
rules share a common repository.
Click Here!
Click Here!
ITKnowledge
As presented earlier in this book, the ISA relationship is a data relationship that
indicates a type/subtype data relationship. While traditional E/R modeling deals only
with single entities, the ISA approach recognizes that many “types” or classes of an
individual entity may exist. In fact, the ISA relationship is the foundation of object-
oriented programming, which allows the designer to create hierarchies of related
classes and then use inheritance and polymorphism to control which data items will
participate in the low-level objects.
The ODMG model creates an independent model that is language independent, and
object models may be bound to many different languages. ODMG develops a
hierarchy of objects with the most general object called a denotable object. Denotable
objects may be mutable or immutable. A mutable object may change its values and
properties, but an immutable object contains only literal values.
Within immutable objects, we find two subcategories: atomic and structured (as shown
in Figure 18.1). A denotable, immutable, atomic object is represented by the same
datatypes found in relational databases, namely char, integer, and float. A denotable,
immutable, structured object is a literal structure such as the date and time datatypes.
Unlike the relational database model, the ODMG model requires that all objects are
assigned an object identifier (OID) to uniquely identify each object. While still
unclear, it appears that it is not possible to reference an object by the data values in the
object. For example, in a relational database, one could state select * from order
where order_nbr = 123; this would not be possible under the current ODMG object
model. Rather, the ODMG model requires database currency to locate the object, and
the system must know the OID.
The ODMG model also categorizes objects according to their lifetime within the
runtime system. Temporary objects, those associated with a procedure or a process, are
classified separately from database objects, which require external storage.
The ODMG object model also attempts to redefine the basic principles of entity/
relationship modeling, but carries the concept one step further, specifying
directionality when navigating the data relationship.
This model also specifies navigational operators to traverse the linked-list data
structures found in commercial implementations of object-oriented databases. These
operators are remarkably similar to the DML found in other pointer-based models,
such as CODASYL, and include verbs such as create, add_member, and traverse.
The model also has database operators that help maintain data integrity. These are
absolutely identical to the CODASYL network data model and have the verbs begin,
commit, abort, and checkpoint. ODMG attempts to recognize the importance of
coexistence with relational databases, and the ODMG model is called a superset of the
relational database model.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduct
Click Here!
Click Here!
ITKnowledge
Please Select
The Future Of Hypermedia In Database Management
Hypermedia has become a very popular term within the arena of database systems.
Many PC-based systems and products advertise themselves as “hypermedia,” but a
comparison of these products shows that they have very little in common.
In basic terms, hypermedia refers to the ability of the database to incorporate audio
and video information. From a database perspective, this audio and video information
is simply other sources, or media. Many databases already allow for the inclusion of
graphical images, and even mainframe databases allow for Binary Large Object
(BLOB) datatypes.
The latest craze within PC-based systems is the inclusion of WAV files. These files
consist of binary audio information and always have the .WAV suffix, such as HORN.
WAV. These files create predetermined sound effects and can be triggered by events
within the system. For example, Microsoft Windows uses video-clip files, which allow
for the inclusion of moving videos within the database.
Many flashy database systems have been created by the addition of audio and video,
and Microsoft corporation implements OLE (pronounced Oh-Lay), which refers to
their Object Linking and Embedding technology.
From a database perspective, these new forms of information are not a problem for the
database designer. Sound effects and moving images are stored in the database and
retrieved on request, just like conventional information. The problem with hypermedia
lies in the effective design and presentation of the hypermedia information.
Hyper in the phrase hypermedia system refers to the ability of the system to allow
links, or calls, to other components within the system that contain ancillary
information. These hyperlinks are commonly used within the Windows environment
and allow the user of the system to dynamically move to other areas of interest. This
concept is analogous to the See also references within encyclopedias. Some text-based
databases, such as the Folio database, allow for linking between textual items.
The real problem with the development of hypermedia systems is the presentation
style of the system. Many vendors create hypermedia shells that allow database
designers to add hypertext links to their applications, and it is very simple for a novice
to create a system that takes advantage of sound and video. Unfortunately, many of
these systems suffer from an artistic overload. Data processing professionals often
have trouble with the feel for the dynamics of an effective presentation system, and the
delivered products are often “noisy” and distracting.
From a data management viewpoint, the same problems that led to the invention of the
first commercial databases are now returning. Thirty years ago, the industry was in the
age of departmental computing, whereby each area within an organization had its own
data processing staff, its own systems, and worst of all, its own data and data
structures. This lack of data sharing is now returning as more departments are
abandoning the mainframe and developing their own systems on PC platforms or
midrange computers.
You should remember that the impetus behind downsizing is primarily monetary.
There is no reason to migrate from a mainframe to smaller systems except for the
cheaper MIPS available on the smaller machines. Unfortunately, many companies are
not only distributing their processing, they are distributing their data, often with
disastrous results.
As more and more companies learn that distributing their data can cause problems at
the corporate level, we will see a move toward the recentralization of data.
This doesn’t mean a return to the mainframe as we know it; it means that very large
amounts of data will be managed and distributed to all platforms within a company.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Experiential Databases
As the cost of computer hardware continues to fall, data processing will undergo
another revolution. Just as the first supercomputers went unnoticed by mainstream
computer professionals, the new hardware technology will emerge with a whisper.
However, the implications toward the way people think about databases will change
dramatically.
Peripheral sensors have been developed that are far superior to human peripherals, but
cognitive development lags far behind. We have cameras that can read a newspaper
headline from outer space and ears that can hear far better than our own, but we have
never mastered the cognitive ability of even the most primitive animal. Every second,
the human mind processes thousands of bits of information. We perceive the distant
humming of fluorescent light bulbs, the pressure of our bodies against our chairs, and
many other perceptions unnoticed by our conscious mind. Numerous researchers in
human cognition hypothesize that the human mind never forgets; what is lost when a
memory is forgotten is the ability to recall the data and not the data itself. Oliver
Sacks, the famous brain surgeon portrayed in the movie Awakenings, related a story in
his fascinating book, The Man Who Mistook His Wife For A Hat. Doctor Sacks was
performing brain surgery on a conscious patient when stimulation to a specific area of
the brain caused the patient to remember a long forgotten incident. Remembering is
not really an appropriate term, because the patient relived the incident and described a
scene from her childhood in such detail that she could sing along with a tune playing
on the Victrola.
When computers advance to the point where storage capacity approaches the capacity
of the human mind, there will be a movement toward experiential database machines.
Experiential machines will perceive the world around them and process information in
a similar fashion to the human mind.
Computers have long been able to learn from experience. Early database experiments
in the 1960s demonstrated that a naive computer could learn the rules to simple games
by playing the game with another computer. However, human reasoning often differs
from computer reasoning—often in very fundamental ways. An excellent example
happened during World War II when the allied forces were planning bombing raids on
Germany.
Attempts at bombing targets in Germany had proved disastrous, with well over one-
half of the aircraft lost. A primitive computer was engaged to solve the problem of
delivering the maximum bomb load while minimizing the amount of lives lost. The
computer was able to prove that less lives would be lost if a smaller number of planes
were sent on the missions. Each of these planes would carry double the bomb load and
just enough fuel to reach their target. After dropping their bombs, the crew would bail
out and take their chances within Axis territory. Assume, for the point of this
argument, that the statistical conclusion was correct, and that less lives would be lost if
these one-way trips were adopted.
The members in the Eighth Air Force were somewhat less than elated with this
proposed solution, and elected to ignore the study. The idea of drawing straws for one-
way trips to Germany was abhorrent to the crew members, even though they had a
much higher probability of survival. Ultimately, the air crews decided to ignore the
study, and hundreds of American lives were lost as a direct result of “irrational”
human cognition.
An experiential system needs to be able to perceive and act upon stimuli in the world.
In order to do so, a model would need to be developed that would allow the database
to retain information in a similar fashion to the human mind. Sigmund Freud
postulated that human memory is persistent. All memories are retained within the
brain, but most are inaccessible. These inaccessible, or unconscious, memories and
experiences are nonetheless present and serve to guide the decision-making abilities of
the human organism. Other psychologists have postulated that the human mind has
very little ability to address detailed memory, and the human mind filters out unneeded
stimuli, storing only what is required for the organism. This filtering mechanism is
activated by priorities set by the conscious mind. For example, a pessimist chooses to
ignore positive stimuli and instead focuses on the bad events of the day. Emotional
reactions also govern what is stored in the mind. The human mind represses, or
blocks, events that are unacceptable to the conscious mind, and would therefore
interrupt the functioning of the organism. These types of filtering devices will need to
be incorporated into the database memory processors, and a great deal will be learned
about the relationship between human and computer cognition.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Please Select
Voice Recognition Database Access
Recognizing a human voice is one of the first things a baby learns, but it’s a very
complex skill for a computer to learn. To create a system with voice recognition, a
method needs to be devised that will allow voice access to database managers.
Unfortunately, computers have had dismal results when learning to parse and
understand human English. It is relatively simple to digitize sound waves for
processing by a computer, but it is very difficult to get a computer to partition the
sounds into words and to recognize where words begin and end. For example,
computers have a hard time recognizing that bus station is two words because the
sounds run together when they are spoken.
Determining the context of spoken English has been a difficult, but not insurmountable
task. Technology has progressed to the point where computers can isolate individual
spoken words and can spell the words according to their context, such as “please write
to Mr. Wright, right now.”
After the spoken words and their individual meanings have been determined, the next
step is to derive the meaning from the sentence. Nonstructured access to databases has
long been of interest to researchers, and several products have come to the
marketplace. Computer Associates markets a product called Online English, which
claims to allow nonstructured queries against their IDMS database product. Other
vendors have created tools that allow macros for the classification of database queries.
For example, a user could state, “All salesmen who have not sold 3,000 products this
month are turkeys.” This establishes a condition set for the word turkey, and a
subsequent query, “Show me the turkeys,” will produce a list of salesmen who have
sold less than 3,000 birds.
Some of this research deals with the translation of English into foreign languages. A
tool was built that translates English into Russian, and a reverse component was
designed to translate Russian into English. The individual components worked
relatively well when presented with well-structured sentences, but more obtuse
sentences produces humorous results. For example, the phrase The spirit is willing but
the flesh is weak, was translated into Russian, and then back into English. When the
translation was complete, the phrase said, The vodka is good, but the meat is rotten.
West publishing company has recently released a tool called Natural, which provides
nonstructured queries against its vast legal database. West claims that the researcher
only needs to state a general concept, and Natural will create a structured query on
behalf of the user, returning the desired information.
Query By Example (QBE) is a database retrieval tool by IBM that allows users to
query their tables without learning SQL. Users of the DB2 database are presented with
a list of database fields that they can combine to create “sample” tables that contain all
of the columns and rows they desire. The user could also specify selection constraints.
QBE will generate the appropriate SQL for the use and return of their query in a
tabular format.
Despite the primitive state of today’s technology, the next 30 years will see a
revolution in ad hoc database access. Tools will be devised allowing users to state a
query to an intelligent front end that will parse the meaning from the statement and
return the results.
Summary
While this chapter may seem futuristic, many of the topics discussed will soon become
commonplace within the world of database management. It remains to be seen how
soon the technology will be changing, but if the current trends in hardware technology
continue, it will not be uncommon to see desktop computers with enough hardware
resources to make artificial intelligence a reality.
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written
permision of EarthWeb is prohibited.
Click Here!
Click Here!
ITKnowledge
Table of Contents
Please Select
Index
Archie, 5
ARPANET, 1
Array, 539
associative, 307
Audio, 46, 155
Audit script, using, 368
Basic, 24
Basic Mapping System. See BMS.
Behaviors, 396
Berners-Lee, Tim, 7
BIF, 291
Bill-of-Materials
explosion, 466
relationships. See BOM relationships.
Binary Large Object. See BLOB.
Bitmap. See BMP.
Black box, 26
BLOB, 551
BMP, 60
BMS, 137
Body procedures, 166
BOM relationships, 466
Bourne shell, 153. See also CGI scripts.
Browser display, 127
Built-in functions. See BIF.
Burleson, Donald K., 438
Bush, Vannevar, 6
C, 154
C or C++, 153
C programming languages, 394
C++, 15, 42, 154, 392, 547. See also Languages, object-oriented.
vs. Java, 395
Caillian, Robert, 7
Cartesian product, 543
Cartridge, 35
Cattributes, 45
CERN, 7
CGI, 33, 34, 36, 112, 151, 278, 405, 420, 441, 503
components, 152–59
origins, 151–52
programming,
common use, 153
languages, 153
programs vs. CGI scripts, 154
scripts, 154, 159, 423
management, 12
Distributed request, 444
Distribution, 485
DML, 15
Domain, 435
Domain name, 9
Domain Name Services, 4
Dynamic page generation, 133
FTP, 3, 5
Fulcrum, 118, 547
Full-table scans, 484, 491, 496, 518, 522, 526, 527, 539
Functional partitioning, 436
Functions, 349
Gallium Arsenide, 15
General Interface Format. See GIF.
Generalization, 28
GIF, 59, 60, 135, 337
GMT, 254, 255, 423
Gopher, 5
Gosling, James, 392
Grant privileges, cascading, 350
Graphical user interface. See GUI.
GreenOS, 392
Greenwich Mean Time. See GMT. See also Time zones.
GUI, 6, 8, 12, 125, 337
Hypermedia, 8
future, 551–52
Hypertext, 6
Hypertext Markup Language. See HTML.
Hypertext Transfer Protocol. See HTTP.
Languages
declarative, 526
object-oriented, 13, 23, 24, 25, 36, 45, 301, 302, 541
procedural, 291, 541
LAN, 11
LaTeX, 11
Link, 46, 376
references, 59
Linux, 394
List procedures, 168
Listener
commands, 449
processes, 112, 452
LiveHTML, 34, 118, 419–29
cartridge, 33, 43
examples, 423–29
Interpreter, 401, 420
similarity to SGML, 421
syntax, 421–23
Local area networks. See LAN.
Local mode, 382
Location transparency, 4, 432, 446
Lock chain, 385
Lock escalation, 384
Lock pool resources, 386
Locking, 489
solution, 379
Locks
exclusive, 381
shared, 381
table-level, 385
Logging features, 145
Logical volume manager. See LVM.
LVM, 520, 521
MacOS, 394
Mailto protocol, 222
Managing Distributed Databases, 438
MAP files, formatting, 158
Massively parallel processors. See MPP.
Master lookup table, 438
McCool, Rob, 152
Memory fencing. See Pinning.
Message, 25
MetaCube, 547
Method, 396
coexistence, 381
Microsoft, 549
Access, 14
Internet Explorer, 11, 64
Visual Basic, 14
Windows, 6, 468, 551
and design issues, 124
MIME, 155, 278
types, 156
Mode
conversational, 378, 382
pseudo-conversational, 378, 382
Model
object-oriented, 16
Morphology, 547
Mosaic, 393
MPP, 500
MS Query, 373
MTS, 439, 440, 449, 450, 451
starting rules of thumb, 451
Multiprocessing, 497
O2 technology, 549
Object
administrator functions, 20
consolidator, 546
Data Management Group. See ODMG.
Design, 549
identifier. See OID.
Linking and Embedding. See OLE.
Management Group. See OMG.
privileges, 348
Request Broker. See ORB.
technology, 12
Object-oriented
approach, 547
database standard architecture, 549
databases, 545
languages. See Languages, object-oriented.
paradigm, 22
Installer, 74–76
uninstalling, 76, 85
Oraperl, 153, 154. See also CGI scripts.
orasrv, 440. See also SQL*Net, listener process.
ORB, 546
OS/2, 394, 497
Overloading, 24
OWA, 34, 77, 159, 338, 404
OWAS, 77, 100, 102
OWA_DBA, 95, 96, 97, 99, 104, 105
OWL, 33, 77, 85, 100, 155, 160, 403, 404, 504
non-reproducible, 382
RI, 482, 483, 486, 494
Roles, 345, 352, 355
creating, 361
Ronco, 23
Router, 11
Row information
updating, 339–44
Rows
phantom, 382
RTF, 11
Rule-based optimizer. See Optimizer, rule-based.
Rules of normalization, 458, 474
Table, 129
HTML vs. Oracle, 243
partial replication, 481
privileges, 346
procedures, 170
UDP, 3
Uniform Resource Locator. See URL.
Universal object manager, 546
Unix, 5, 424
documentation screen, 83
Updatable snapshots, 474
Update procedure, 303
UPI, 440, 441
URL, 8, 59, 85, 112, 280
components, 9
format, 9
User Datagram Protocol. See UDP.
Versant, 549
Vertical partition, 432, 436
VID files, 120
Video, 46, 155
Views, 357
Virtual reality environments. See VRML.
Visual Basic, 153
Voice Recognition Database Access, 556–57
VRML, 120
WAIS, 3, 5
WAN, 1, 2
Web listener, 32, 33, 34, 35, 190
Web page
constructs, 46
definition, 46
vs. SQL*Form or PowerBuilder, 126, 319
Web Request Broker. See WRB.
Web technology, 8
Web Transaction Manager, 43–44
WebMaster, 161
WebServer, 29, 38–39, 312
3.0, 121
Administrative Server, default port, 92
applications, 118–19
basic components, 33
configuring WebServer 1, 94–100
configuring WebServer 2, 100–05
differences between versions 1 and 2, 34
installing WebServer 1, 76–85
installing WebServer 2, 85–93
primary purpose, 32
real benefit, 41
using, 71
West Publishing Company, 557
Whitney, Eli, 13
Wide-Area Information Servers. See WAIS.
Wide-area network. See WAN.
Widgets, 125, 126
Wildcards, extensions, 257
Windows, 394
Windows NT, 497
Windows Standard Development Kit. See SDK.
Wizards, 15
World Wide Web, 6, 12
elements, 8
origin, 7
principles, 7
Wrappers, 405
WRB, 33, 34, 36, 85, 112, 151, 159, 160, 278, 378, 401, 402, 403, 404, 405,
420, 441, 448, 503, 504
executable engine. See WRBX.
services, 86
vs. CGI, 35, 112, 161
WRBX, 36, 85
WWW, 5
Zone names, 9
Table of Contents