Шрифт:
Процедура не обязательно должна существовать, однако будьте внимательны с чувствительностью к регистру в именах объектов, если при создании процедуры используются идентификаторы, заключенные в апострофы. Предположим, вы создаете следующую процедуру:
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 и владелец процедуры могут ее удалять.