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

Tuning PL/SQL Procedure Calls with the NOCOPY Compiler Hint

run time. Such statements probably change from execution to execution. They are called dynamic SQL statements.

Formerly, to execute dynamic SQL statements, you had to use the supplied package DBMS_SQL. Now, within PL/SQL, you can execute any kind of dynamic SQL statement using an interface called native dynamic SQL. The main PL/SQL features involved are the EXECUTE IMMEDIATE statement and cursor variables (also known as

REF CURSORs).

Native dynamic SQL code is more compact and much faster than calling the DBMS_SQL package. The following example declares a cursor variable, then associates it with a dynamic SELECT statement:

DECLARE

TYPE EmpCurTyp IS REF CURSOR;

emp_cv

EmpCurTyp;

my_ename

VARCHAR2(15);

my_sal

NUMBER := 1000;

table_name VARCHAR2(30)

:= 'employees';

BEGIN

 

OPEN emp_cv FOR 'SELECT

last_name, salary FROM ' || table_name ||

' WHERE salary > :s'

USING my_sal;

CLOSE emp_cv;

 

END;

 

/

 

For more information, see Chapter 7.

Tuning PL/SQL Procedure Calls with the NOCOPY Compiler Hint

By default, OUT and IN OUT parameters are passed by value. The values of any IN OUT parameters are copied before the subprogram is executed. During subprogram execution, temporary variables hold the output parameter values. If the subprogram exits normally, these values are copied to the actual parameters. If the subprogram exits with an unhandled exception, the original parameters are unchanged.

When the parameters represent large data structures such as collections, records, and instances of object types, this copying slows down execution and uses up memory. In particular, this overhead applies to each call to an object method: temporary copies are made of all the attributes, so that any changes made by the method are only applied if the method exits normally.

To avoid this overhead, you can specify the NOCOPY hint, which allows the PL/SQL compiler to pass OUT and IN OUT parameters by reference. If the subprogram exits normally, the behavior is the same as normal. If the subprogram exits early with an exception, the values of OUT and IN OUT parameters (or object attributes) might still change. To use this technique, ensure that the subprogram handles all exceptions.

The following example asks the compiler to pass IN OUT parameter MY_STAFF by reference, to avoid copying the varray on entry to and exit from the subprogram:

DECLARE

TYPE Staff IS VARRAY(200) OF Employee;

PROCEDURE reorganize (my_staff IN OUT NOCOPY Staff) IS ...

BEGIN NULL;

END;

/

11-20 PL/SQL User's Guide and Reference

Tuning PL/SQL Procedure Calls with the NOCOPY Compiler Hint

The following example loads 25,000 records into a local nested table, which is passed to two local procedures that do nothing. A call to the procedure that uses NOCOPY takes much less time.

DECLARE

TYPE EmpTabTyp IS TABLE OF employees%ROWTYPE; emp_tab EmpTabTyp := EmpTabTyp(NULL); -- initialize t1 NUMBER;

t2 NUMBER;

t3 NUMBER;

PROCEDURE get_time (t OUT NUMBER) IS BEGIN t := dbms_utility.get_time; END;

PROCEDURE do_nothing1 (tab IN OUT EmpTabTyp) IS BEGIN NULL; END;

PROCEDURE do_nothing2 (tab IN OUT NOCOPY EmpTabTyp) IS BEGIN NULL; END;

BEGIN

SELECT * INTO emp_tab(1) FROM employees WHERE employee_id = 100; emp_tab.EXTEND(49999, 1); -- copy element 1 into 2..50000 get_time(t1);

do_nothing1(emp_tab); -- pass IN OUT parameter get_time(t2);

do_nothing2(emp_tab); -- pass IN OUT NOCOPY parameter get_time(t3);

dbms_output.put_line('Call Duration (secs)'); dbms_output.put_line('--------------------'); dbms_output.put_line('Just IN OUT: ' || TO_CHAR((t2 - t1)/100.0)); dbms_output.put_line('With NOCOPY: ' || TO_CHAR((t3 - t2))/100.0);

END;

/

Restrictions on NOCOPY

The use of NOCOPY increases the likelihood of parameter aliasing. For more information, see "Understanding Subprogram Parameter Aliasing".

Remember, NOCOPY is a hint, not a directive. In the following cases, the PL/SQL compiler ignores the NOCOPY hint and uses the by-value parameter-passing method; no error is generated:

The actual parameter is an element of an associative array. This restriction does not apply if the parameter is an entire associative array.

The actual parameter is constrained, such as by scale or NOT NULL. This restriction does not apply to size-constrained character strings. This restriction does not extend to constrained elements or attributes of composite types.

The actual and formal parameters are records, one or both records were declared using %ROWTYPE or %TYPE, and constraints on corresponding fields in the records differ.

The actual and formal parameters are records, the actual parameter was declared (implicitly) as the index of a cursor FOR loop, and constraints on corresponding fields in the records differ.

Passing the actual parameter requires an implicit datatype conversion.

The subprogram is called through a database link or as an external procedure.

Tuning PL/SQL Applications for Performance 11-21

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