Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
16.04.2013
Размер:
5.97 Mб
Скачать

Overloading Subprogram Names

Table 8–1 (Cont.) Parameter Modes

IN

OUT

IN OUT

Passes values to a subprogram

Formal parameter acts like a constant

Formal parameter cannot be assigned a value

Actual parameter can be a constant, initialized variable, literal, or expression

Actual parameter is passed by reference (a pointer to the value is passed in)

Returns values to the caller

Formal parameter acts like an uninitialized variable

Formal parameter must be assigned a value

Actual parameter must be a variable

Actual parameter is passed by value (a copy of the value is passed out) unless NOCOPY is specified

Passes initial values to a subprogram and returns updated values to the caller

Formal parameter acts like an initialized variable

Formal parameter should be assigned a value

Actual parameter must be a variable

Actual parameter is passed by value (a copy of the value is passed in and out) unless NOCOPY is specified

Using Default Values for Subprogram Parameters

By initializing IN parameters to default values, you can pass different numbers of actual parameters to a subprogram, accepting the default values for any parameters you omit. You can also add new formal parameters without having to change every call to the subprogram.

Example 8–6 Procedure with Default Parameter Values

PROCEDURE create_dept (

new_dname

VARCHAR2 DEFAULT 'TEMP',

new_loc

VARCHAR2 DEFAULT 'TEMP') IS

BEGIN

 

NULL;

 

END;

 

/

 

If a parameter is omitted, the default value of its corresponding formal parameter is used. Consider the following calls to create_dept:

create_dept;

--

Same as create_dept('TEMP','TEMP');

create_dept('SALES');

-- Same as create_dept('SALES','TEMP');

create_dept('SALES', 'NY');

 

You cannot skip a formal parameter by leaving out its actual parameter. To omit the first parameter and specify the second, use named notation:

create_dept(new_loc => 'NEW YORK');

You cannot assign a null to an uninitialized formal parameter by leaving out its actual parameter. You must pass the null explicitly, or you can specify a default value of NULL in the declaration.

Overloading Subprogram Names

PL/SQL lets you overload subprogram names and type methods. You can use the same name for several different subprograms as long as their formal parameters differ in number, order, or datatype family.

Using PL/SQL Subprograms 8-9

Overloading Subprogram Names

Suppose you want to initialize the first n rows in two index-by tables that were declared as follows:

DECLARE

TYPE DateTabTyp IS TABLE OF DATE INDEX BY BINARY_INTEGER; TYPE RealTabTyp IS TABLE OF REAL INDEX BY BINARY_INTEGER; hiredate_tab DateTabTyp;

sal_tab RealTabTyp; BEGIN

NULL;

END;

/

You might write a procedure to initialize one kind of collection:

PROCEDURE initialize (tab OUT DateTabTyp, n INTEGER) IS BEGIN

FOR i IN 1..n LOOP tab(i) := SYSDATE;

END LOOP; END initialize;

/

You might also write a procedure to initialize another kind of collection:

PROCEDURE initialize (tab OUT RealTabTyp, n INTEGER) IS BEGIN

FOR i IN 1..n LOOP tab(i) := 0.0;

END LOOP; END initialize;

/

Because the processing in these two procedures is the same, it is logical to give them the same name.

You can place the two overloaded initialize procedures in the same block, subprogram, package, or object type. PL/SQL determines which procedure to call by checking their formal parameters. In the following example, the version of initialize that PL/SQL uses depends on whether you call the procedure with a

DateTabTyp or RealTabTyp parameter:

DECLARE

TYPE DateTabTyp IS TABLE OF DATE INDEX BY BINARY_INTEGER; TYPE RealTabTyp IS TABLE OF REAL INDEX BY BINARY_INTEGER; hiredate_tab DateTabTyp;

comm_tab RealTabTyp; indx BINARY_INTEGER;

PROCEDURE initialize (tab OUT DateTabTyp, n INTEGER) IS BEGIN

NULL;

END;

PROCEDURE initialize (tab OUT RealTabTyp, n INTEGER) IS BEGIN

NULL;

END; BEGIN

indx := 50;

initialize(hiredate_tab, indx); -- calls first version initialize(comm_tab, indx); -- calls second version

END;

/

8-10 PL/SQL User's Guide and Reference

Overloading Subprogram Names

Guidelines for Overloading with Numeric Types

You can overload two subprograms if their formal parameters differ only in numeric datatype. This technique might be useful in writing mathematical APIs, where several versions of a function could use the same name, each accepting a different numeric type. For example, a function accepting BINARY_FLOAT might be faster, while a function accepting BINARY_DOUBLE might provide more precision.

To avoid problems or unexpected results passing parameters to such overloaded subprograms:

Make sure to test that the expected version of a subprogram is called for each set of expected parameters. For example, if you have overloaded functions that accept

BINARY_FLOAT and BINARY_DOUBLE, which is called if you pass a VARCHAR2 literal such as '5.0'?

Qualify numeric literals and use conversion functions to make clear what the intended parameter types are. For example, use literals such as 5.0f (for BINARY_FLOAT), 5.0d (for BINARY_DOUBLE), or conversion functions such as

TO_BINARY_FLOAT(), TO_BINARY_DOUBLE(), and TO_NUMBER().

PL/SQL looks for matching numeric parameters starting with PLS_INTEGER or

BINARY_INTEGER, then NUMBER, then BINARY_FLOAT, then BINARY_DOUBLE. The first overloaded subprogram that matches the supplied parameters is used. A

VARCHAR2 value can match a NUMBER, BINARY_FLOAT, or BINARY_DOUBLE parameter.

For example, consider the SQRT function, which takes a single parameter. There are overloaded versions that accept a NUMBER, a BINARY_FLOAT, or a BINARY_DOUBLE parameter. If you pass a PLS_INTEGER parameter, the first matching overload (using the order given in the preceding paragraph) is the one with a NUMBER parameter, which is likely to be the slowest. To use one of the faster versions, use the TO_BINARY_FLOAT or TO_BINARY_DOUBLE functions to convert the parameter to the right datatype.

For another example, consider the ATAN2 function, which takes two parameters of the same type. If you pass two parameters of the same type, you can predict which overloaded version is used through the same rules as before. If you pass parameters of different types, for example one PLS_INTEGER and one BINARY_FLOAT, PL/SQL tries to find a match where both parameters use the "higher" type. In this case, that is the version of ATAN2 that takes two BINARY_FLOAT parameters; the PLS_INTEGER parameter is converted "upwards".

The preference for converting "upwards" holds in more complicated situations. For example, you might have a complex function that takes two parameters of different types. One overloaded version might take a PLS_INTEGER and a BINARY_FLOAT parameter. Another overloaded version might take a NUMBER and a BINARY_DOUBLE parameter. What happens if you call this procedure name and pass two NUMBER parameters? PL/SQL looks "upward" first to find the overloaded version where the second parameter is BINARY_FLOAT. Because this parameter is a closer match than the BINARY_DOUBLE parameter in the other overload, PL/SQL then looks "downward" and converts the first NUMBER parameter to PLS_INTEGER.

Restrictions on Overloading

Only local or packaged subprograms, or type methods, can be overloaded. You cannot overload standalone subprograms.

Using PL/SQL Subprograms 8-11

Соседние файлы в папке Oracle 10g