Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming PL SQL.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
5.06 Mб
Скачать

20.5 Pl/sql Code on the Client

If you are using Oracle's application development tools, such as Forms or Reports, you can use PL/SQL as the language in which you create an application's graphical user interface and supporting logic. Technically, you don't even have to connect to a database to use this feature. Also, with a little effort, you can even hook up client-side PL/SQL to databases other than Oracle. The normal arrangement, though, looks like Figure 20-10.

Figure 20-10. Oracle client-side runtime environment invoking a stored procedure

As illustrated, the client-side runtime environment—which may actually be running on a middle tier, such as an Oracle Forms "server"—communicates with both the server-side PL/SQL runtime and the server's SQL processing components. The remote procedure calls don't require the server to read the DIANA of any called programs in order to determine whether the referenced program has changed, as discussed earlier in Section 20.2.4 of this chapter.

One of the great things that Oracle has done with the application development tools is to provide a wide range of extended functionality via built-in packages. So, on the client computer, for example, you can use PL/SQL to do things like:

  • Define the behaviors of triggers that fire on events such as mouse clicks

  • Provide data entry assistance to the user by encoding automatic lookups and data validation

  • Specify what will happen when the user selects an item from a pull-down menu

  • Store and retrieve data in local files using the TEXT_IO package

  • Programmatically alter behavior and visual characteristics of user interface widgets

Up through Developer 6i, you could also use PL/SQL to interact with the client operating system. For example, on Microsoft Windows you could call DLLs directly, use OLE (Object Linking and Embedding) features, or make calls to the Windows API. Oracle eliminated those Microsoft-specific features in Developer 9i, though. No comment.

Fortunately, making direct calls to server-side PL/SQL from the client PL/SQL environment is subject to only a few gotchas. For starters, because the client version of PL/SQL is released on a different schedule from the server version, you cannot always assume that some particular language feature is available. You need to be aware of what version of PL/SQL you have on the client.

20.5.1 Supported Versions and Features

You can always discover which version of PL/SQL is running on the client by choosing Help About from the menu of the Developer tool. A partial version matrix appears in Table 20-3, but note that any patches you may have installed could cause the nth decimal place to differ from this table.

Table 20-3. Client-side PL/SQL versions

Oracle Developer version (base release)

Oracle Forms

version

PL/SQLversion

1.x

4.5

1.2

2.x

5.0

2.3

6.0

6.0.5

8.0.5

6i

6.0.8

8.0.6

9i

9.0.2

9.0.1

The next thing to realize is that just because the client has a particular PL/SQL release, that does not mean you have access to all of the corresponding server features you might expect from that version. With client PL/SQL 9.0.2, for example, you can do any of these things:

  • Declare and use a local collection type inside a client program (and declare and use local variables of that type).

  • Use a subtype, collection type, record type, or cursor variable type that has been declared in a package spec on the server.

  • Declare a variable in a client program of a type that has been declared in a server-based package specification. This includes records and single-level collections.

  • Declare and use variables as REFs to a user-defined object type.

  • Base a block on a table with a collection-typed attribute.

  • Base a block on an object table or on a table with an object column, as long as the object type does not include a collection-typed attribute.

But (and this is still on the client side, remember) you cannot:

  • Create a standalone user-defined type (such as an object type or collection type).

  • Declare a variable in a client program that is of a standalone user-defined type you have declared on the server.

There are two ways to work around this problem:

  • Do not use any unsupported datatypes in the specifications of your server-side stored modules.

  • Write a thin "translator" stored procedure to map server-side PL/SQL datatypes to the datatypes available on your client version of PL/SQL (where possible).

I strongly urge you to employ the second workaround. If you have built stored programs that make use of server-side PL/SQL datatypes in the parameter list, and if those datatypes are the most appropriate ones for the parameters, you shouldn't change that module's specification. You should always try to take advantage of the most advanced features of a language. Don't choose a lowest-common-denominator solution unless there are no other options.

In many situations, you won't have the opportunity to change the specification (parameter list) of a stored module. It might have been written by others, perhaps for another application, and cannot be modified without possibly affecting those other applications. In this case, the second workaround is annoying, but is thoroughly able to be implemented. If your pre-Oracle9i client-side code must call a procedure that accepts a TIMESTAMP parameter, for example, it may make sense to encapsulate it inside another stored procedure that instead accepts a DATE. In fact, you could just overload the procedure if it's in a package. Here is the specification:

PACKAGE logger

AS

PROCEDURE note_the_time (event_time_in IN TIMESTAMP);

PROCEDURE note_the_time (event_time_in IN DATE);

END;

The package body would include the following implementation of the DATE version:

PROCEDURE note_the_time (event_time_in IN DATE) IS

BEGIN

note_the_time(TO_TIMESTAMP(event_time_in));

END;

Now logger.note_the_time can be called from a pre-9i client program because it accepts one of the supported datatypes.

When implementing overloading to support different datatypes, do not rely on implicit type conversions in the body of the procedure. I tried that:

PROCEDURE note_the_time (event_time_in IN DATE) IS

BEGIN

note_the_time(event_time_in); /* bad idea */

END;

Yup, that's an infinite recursive loop, and the means of escaping from it is not obvious (kill the shadow task using orakill.exe on Windows platforms, or kill -9 on Unix). No doubt a real DBA would have long ago imposed CPU limits with Oracle's "profile" feature on a guy like me.

Note that if you are using Forms 9i, you won't have this particular problem with TIMESTAMP because it is a supported datatype. You will, however, run into another annoyance when you attempt to use server-side package variables, as the next section illustrates.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]