Читать интересную книгу Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 136 137 138 139 140 141 142 143 144 ... 238

Процедуры для совместного использования

Хотя возможно написание процедуры выбора, которая будет выполнять операции по изменению данных в процессе конструирования выходного набора, этого делать не рекомендуется. Хранимая процедура выбора разрабатывается для вывода набора данных клиенту в контексте вызвавшей ее транзакции. Пока клиентское приложение не завершит использование этого выходного набора, транзакция остается неподтвержденной. Если операции DML включены в код, который генерирует выходной набор, эти запросы DML остаются неподтвержденными, пока транзакция не будет завершена клиентом.

В частности, данные могут потенциально сохраняться в несогласованном виде, если значения выхода хранимой процедуры выступают в качестве параметров для операций в других транзакциях.

Изменение хранимых процедур

Firebird 1.0.x предоставляет два способа изменения хранимых процедур с использованием операторов DDL, a Firebird 1.5 добавляет еще и третий. Это:

* оператор ALTER PROCEDURE, который изменяет определение существующей хранимой процедуры, сохраняя ее взаимозависимости с другими объектами;

* оператор RECREATE PROCEDURE, который выполняется, даже если указанная процедура не существует. Если она существует, то эта версия удаляется, а затем заново создается. Существующие зависимости не сохраняются;

* оператор CREATE OR ALTER PROCEDURE (доступен начиная с версии 1.5) предоставляет лучший вариант. Если процедура существует, применяются правила ALTER, зависимости сохраняются. Если не существует, то будет работать точно так же, как и CREATE PROCEDURE.

Любая из этих операций вызовет исключение, если любая попытка изменений разрушает зависимости.

Влияние на приложения

Внутренние изменения процедуры прозрачны всем клиентским приложениям, использующим эту процедуру. Вам не нужно пересоздавать приложения, если изменения не коснулись интерфейса между вызывающей программой и процедурой - тип, количество или порядок выходных или выходных аргументов.

Синтаксис изменения процедур

За исключением ключевого слова, которое вы выбрали для изменения хранимой процедуры, синтаксис для всех операторов такой же, как и для CREATE PROCEDURE. Как и в любом другом компилируемом или интерпретируемом модуле, не существует способов непосредственного изменения элементов без полного пересоздания всего модуля. Каждая "переделка", независимо от выбранного ключевого слова для задания операции, имеет дело с созданием новой версии исходного кода и нового двоично- кодированного объекта.

Синтаксис:

{CREATE | ALTER | RECREATE | CREATE OR ALTER} PROCEDURE Имя

[(переменная тип-данных [,переменная тип-данных ...])]

[RETURNS (переменная тип-данных [, переменная тип-данных ...])]

AS

тело-процедуры;

ALTER PROCEDURE

В ALTER PROCEDURE имя процедуры должно быть именем существующей процедуры.

Это мягкий способ изменения кода процедуры, потому что если у нее есть зависимости, на которые логически не влияют изменения, то они не будут влиять на структурную часть.

Вообще, не оказывается влияния на зависимости, включающие другие объекты, которые зависят от измененной процедуры. При этом, если изменения хранимой процедуры изменяют определения ее входных и выходных аргументов, нужно будет выполнить RECREATE PROCEDURE для любой другой процедуры, к которой происходит обращение в процессе выполнения.

! ! !

ВНИМАНИЕ! Некоторые версии Firebird 1.0.x обнаруживают ошибку, когда зависимые объекты выдают исключение при перекомпиляции зависимого объекта, даже если изменения не оказывали воздействия на интерфейс между объектами.

. ! .

RECREATE PROCEDURE

Оператор RECREATE PROCEDURE идентичен оператору CREATE PROCEDURE за исключением того, что для существующей процедуры с тем же именем он внутренне выполняет операцию DROP PROCEDURE перед созданием нового двоичного объекта. Имя процедуры не должно существовать.

Вы можете использовать его, как и 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.

CREATE OR ALTER PROCEDURE

Новый в версии 1.5 синтаксис создает новую процедуру, если не существует процедуры с тем же именем, иначе изменяет ее.

Исправление процедуры LOG_SALES

Как пример, мы собираемся исправить процедуру 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.

* Если другие объекты ссылаются или вызывают данную процедуру, то необходимо сначала изменить зависимые объекты, удалив такие ссылки и подтвердив работу, прежде чем удалять процедуру.

* Для удаления рекурсивной процедуры необходимо сначала удалить рекурсивные вызовы и подтвердить изменения. Похожие трудности существуют и для процедуры, вызывающей другую процедуру, которая в свою очередь вызывает процедуру, которую вы собираетесь удалить. Все подобные зависимости должны быть удалены и подтверждены, чтобы процедура стала доступной для удаления.

Тема оптимизации: использование внутренних возможностей

Firebird наследует недокументированную возможность, которая может ускорить выполнение запроса при некоторых условиях. Это RDB$DB_KEY (обычно называется просто db key), внутренний ключ, поддерживаемый сервером базы данных для внутреннего использования при оптимизации запросов и управлении версиями записей. Внутри контекста транзакции, где он используется, он представляет позицию строки в таблице8[118].

1 ... 136 137 138 139 140 141 142 143 144 ... 238
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри.
Книги, аналогичгные Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Оставить комментарий