Вы можете использовать его, как и ALTER PROCEDURE, однако оно не сохраняет существующие зависимости. Операция будет заблокирована, если существуют зависимые объекты (просмотры или другие процедуры, которые ссылаются на данную процедуру).
Процедура не обязательно должна существовать, однако будьте внимательны с чувствительностью к регистру в именах объектов, если при создании процедуры используются идентификаторы, заключенные в апострофы. Предположим, вы создаете следующую процедуру:
CREATE PROCEDURE "Try_Me"
RETURNS (AWORD VARCHAR(10))
AS
BEGIN
AWORD = 'turtle';
END ^
Теперь вы решаете изменить ее с использованием RECREATE PROCEDURE:
RECREATE PROCEDURE Try_Me
RETURNS (AWORD VARCHAR(10))
AS
BEGIN
AWORD = 'Venezuela';
END ^
Исходная процедура с именем, чувствительным к регистру Try_Me, сохраняется неизмененной. "Заново созданная" процедура является новой процедурой с именем, не чувствительным к регистру - TRY_ME.
Новый в версии 1.5 синтаксис создает новую процедуру, если не существует процедуры с тем же именем, иначе изменяет ее.
Как пример, мы собираемся исправить процедуру LOG_SALES, которая обещает доставить нам неприятности, потому что мы не обратили внимание на пустые значения ключей. Вот блок, который может решить проблемы:
CREATE PROCEDURE LOG_SALES ( . . .
. . .
DO
BEGIN
IF(REP = LASTREP) THEN
/* будет иметь значение false, если оба значения null */
BEGIN
REPTOTAL = REPTOTAL + ORDTOTAL;
REP_NAME = "" ;
END
ELSE
BEGIN
REPTOTAL = ORDTOTAL;
LASTREP = REP;
SELECT FULL_NAME FROM EMPLOYEE
WHERE EMP_NO = :REP
INTO :REP_NAME;
/* вернет null, если переменная REP имеет значение null */
END
. . .
END ^
Мы исправили логику для обработки пустых значений (сгруппированных вместе в конце курсора, потому что набор упорядочен по этому столбцу) и используем операторы CREATE или ALTER для изменения кода:
CREATE OR ALTER PROCEDURE LOG_SALES (...
. . .
DO
BEGIN
* ************ */
IF((REP = LASTREP) OR (LASTREP IS NULL)) THEN
/* ************ */
BEGIN
REPTOTAL = REPTOTAL + ORDTOTAL;
REP_NAME = "" ;
END
ELSE
BEGIN
REPTOTAL = ORDTOTAL;
LASTREP = REP;
/* ************* */
IF (REP IS NOT NULL) THEN
SELECT FULL_NAME FROM EMPLOYEE
WHERE EMP_NO = : REP
INTO :REP_NAME;
ELSE
REP_NAME = ' Onassigned ' ;
/* ************* */
END
. . .
END ^
COMMIT ^
Подтверждение изменения вызовет пресловутую ошибку (обсуждавшуюся в предыдущей главе), если какой-нибудь пользователь в настоящий момент использует эту процедуру или любой другой объект, зависящий от нее. Даже если мы уберем это препятствие, новая версия процедуры не станет немедленно доступной в Суперсервере, если старая версия все еще находится в кэше. Все пользователи должны отключиться от базы данных, а когда они снова к ней подключатся, они смогут увидеть новую версию.
В Классическом сервере новая версия будет доступна следующему клиенту, который соединится с базой данных.
Удаление хранимых процедур
Оператор DROP PROCEDURE удаляет существующую хранимую процедуру из базы данных. Вы можете использовать этот оператор везде, где можно использовать операторы DDL.
! ! !
ПРИМЕЧАНИЕ. Операторы DDL не могут выполняться как операторы PSQL. При этом в Firebird 1.5 оператор DDL может передаваться через конструкцию EXECUTE STATEMENT. Нужно ли читающему пользователю быть осторожным в отношении использования EXECUTE STATEMENT при удалении самой процедуры?
. ! .
Синтаксис:
DROP PROCEDURE имя;
имя процедуры должно быть именем существующей процедуры. Будьте внимательны в отношении чувствительности к регистру имен объектов, если при создании процедуры были использованы идентификаторы в апострофах.
Следующий оператор удаляет процедуру LOG_SALES:
DROP PROCEDURE LOG_SALES;
Ограничения
При удалении процедуры существуют ограничения.
* Только пользователь SYSDBA и владелец процедуры могут ее удалять.
* Процедура, находящаяся в использовании в любой другой транзакции, не может быть удалена. Это является особой проблемой в системах, где процедуры вызываются в транзакциях, которые подтверждаются с использованием
CommitRetaining.
* Если другие объекты ссылаются или вызывают данную процедуру, то необходимо сначала изменить зависимые объекты, удалив такие ссылки и подтвердив работу, прежде чем удалять процедуру.
* Для удаления рекурсивной процедуры необходимо сначала удалить рекурсивные вызовы и подтвердить изменения. Похожие трудности существуют и для процедуры, вызывающей другую процедуру, которая в свою очередь вызывает процедуру, которую вы собираетесь удалить. Все подобные зависимости должны быть удалены и подтверждены, чтобы процедура стала доступной для удаления.
Тема оптимизации: использование внутренних возможностей