В Oracle 8 и выше существует специальное указание компилятору — NOCOPY. Синтаксис объявления параметра с этим модификатором таков:
[вид] NOCOPY
где — это имя параметра, вид — вид параметра (IN, OUT
или IN OUT), а тип данных — тип параметра. Если задано NOCOPY, компилятор PL/SQL пытается передать параметр по ссылке, а не по значению. NOCOPY — это указание компилятору, а не директива, поэтому не всегда принимается (см. ниже). Рассмотрим пример:
При указании NOCOPY для параметра IN генерируется ошибка компиляции, поскольку параметры IN всегда передаются по ссылке и NOCOPY к ним не применим.
Семантика исключительных ситуаций при использовании NOCOPY
При модификации фактического параметра, передаваемого по ссылке, изменяется и формальный параметр, так как оба они указывают на одну и ту же область памяти. Это значит, что при выходе из процедуры с необработанной исключительной ситуацией после изменения формального параметра исходное значение фактического параметра теряется. Модифицируем RaiseError, указав NOCOPY:
••- Этот пример содержится в файле NoCopyTest. sql
CREATE OR REPLACE PROCEDURE RaiseError (
p_Raise IN BOOLEAN,
p_ParameterAOUT NOCOPY NUMBER) AS BEGIN
p_ParameterA := 7;
IF p_Raise THEN
RAISE DUP_VAL_ON_INDEX;
ELSE
RETURN;
END IF; END RaiseError;
Единственное изменение здесь в том, что параметр теперь передается по ссылке, а не по значению. Предположим, что RaiseError вызывается так:
Это тот самый блок, который рассматривался в разделе "Исключительные ситуации, устанавливаемые в подпрограммах". Результат же теперь
иной:
Фактический параметр изменился в обоих случаях, даже при установке исключительной ситуации.
Ограничения на использование NOCOPY
В некоторых случаях указание NOCOPY игнорируется и параметр передается по значению. При этом никаких ошибок не генерируется. не забывайте о том, что nocopy -это указание, и компилятор не обязан всегда следовать ему. NOCOPY игнорируется в следующих ситуациях:
Фактический параметр является членом индексной таблицы. Если же фактический параметр — вся таблица, это ограничение не действует.
Фактический параметр ограничен точностью, масштабом или значением NOT NULL. Однако это не применимо по отношению к символьным параметрам, ограниченным максимальной длиной. Дело в том, что компилятор PL/SQL проверяет нарушения ограничений только при возвращении из подпрограммы, т.е. при копировании
значения из формального параметра в фактический параметр. Если
имеется нарушение ограничения, первоначальное значение фактического параметра необходимо изменить, что невозможно в случае NOCOPY.
• И фактический, и формальный параметры являются записями, объявленными либо неявно, как в случае управляющей переменной цикла, либо при помощи %ROWTYPE, а ограничения соответствующих полей отличаются друг от друга.
Для передачи фактического параметра необходимо неявно преобразовывать типы данных.
Подпрограмма выполняется во время вызова удаленной процедуры (RPC, remote procedure call), т.е. при вызове процедуры на удаленном сервере посредством соединения с базой данных. Так как параметры должны передаваться по сети, то их невозможно передать по ссылке.
Совет
Если подпрограмма является частью RPC, NOCOPY игнорируется. Если модифицировать существующее приложение, внеся вместо локальных несколько вызовов RPC, то семантика исключительных ситуаций может измениться.
< Предыдущая | Следующая > |
---|