Выбрать главу
Ошибка "Объект находится в использовании"

Ошибка "Object is in use" (Объект находится в использовании) расстраивает разработчика более чем какая-либо другая. Вы соединились с базой данных как пользователь SYSDBA или владелец базы данных. У вас исключительный доступ, что желательно при изменении метаданных, и вдруг появляется какой-то фантомный пользователь, использующий объект, метаданные которого вы собираетесь изменить или удалить.

Источником этой загадки может быть одна или более следующих ситуаций.

* При останове базы данных (shut down), подготовке к получению исключительного доступа вы (или другой человек) уже были соединены как пользователь SYSDBA, владелец или (в Linux/UNIX) как пользователь с подходящими привилегиями операционной системы. При проверке условий останова базы данных Firebird игнорирует таких пользователей и все их текущие транзакции или те, которые запускаются после начала останова. Любая неподтвержденная транзакция (какой бы она ни была - даже SELECT), которая использует этот объект или любой объект, зависящий от этого объекта, или объект, от которого зависит наш объект, будет вызывать эту ошибку.

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

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

! ! !

ВНИМАНИЕ! Такая ситуация может провоцировать цепочку несогласованностей в вашей базе данных. Например, если gbak выполнялся в то время, когда база данных имела объекты в таком состоянии, то восстановление резервной копии может оказаться невозможным.

Всякий раз, когда вы видите такую ошибку и верите, что вы насколько возможно уменьшили вероятность ее появления, рассматривайте ее как сигнал, что ваша база данных нуждается в проверке до того, как вы продолжите любые дальнейшие изменения метаданных (см. главу 39).

. ! .

Для просмотра в isql списка процедур или триггеров и их зависимостей используйте команду SHOW PROCEDURES или SHOW TRIGGERS соответственно.

Удаление исходных текстов модулей

Разработчики часто хотят "спрятать" исходные коды их модулей PSQL при распространении баз данных. Вы можете удалить хранимые исходные тексты без воздействия на возможности модуля. Только убедитесь, что у вас есть последние версии скриптов, прежде чем это делать!

Исходные тексты всех модулей хранятся в системной таблице RDB$PROCEDURES и RDB $ TRIGGERS.

Удаление исходного текста процедуры:

UPDATE RDB$PROCEDURES

SET RDB$PROCEDURE_SOURCE = NULL

WHERE RDB$PROCEDURE NAME = 'MYPROC';

Удаление исходного текста триггера:

UPDATE RDB$TRIGGERS

SET RDB$TRIGGER_SOURCE = NULL

WHERE RDB$TRIGGER_NAME = 'MYTRIGGER';

! ! !

ВНИМАНИЕ! Имейте в виду, что такое удаление исходных кодов не остановит тех, кто серьезно собирается украсть ваш исходный код. Исполняемый код хранится в двоичном формате, который очень просто может быть преобразован обратно в PSQL. Следовательно, решите, будет ли выгода от утаивания PSQL больше затрат, которые вы и другие, кто поддерживает систему, понесут от потери возможности просмотра и выделения исходного текста.

. ! .

Пора дальше

Далее мы подробно рассмотрим возможности языка PSQL и техники, которые вы можете использовать для разработки хранимых процедур и структуризации вашего кода. Специальная тема в конце главы описывает RDB$DB_KEY, внутренний уникальный атрибут каждой строки в каждом наборе, который может быть полезен при оптимизации выполнения некоторых операций PSQL.

ГЛАВА 30. Хранимые процедуры.

Процедура является самостоятельной программой, написанной на языке PSQL Firebird, скомпилированной интерпретатором во внутренний двоичный язык Firebird и сохраненной как исполняемый код в метаданных базы данных. Однажды скомпилированная, хранимая процедура может быть вызвана непосредственно из приложения или другого модуля PSQL с использованием оператора EXECUTE PROCEDURE или SELECT в соответствии с заданным стилем процедуры.

Хранимые процедуры могут принимать входные параметры от клиентских приложений в качестве аргументов вызываемого запроса. Они могут возвращать приложениям набор значений в качестве выходных параметров.

Язык процедур и триггеров Firebird включает SQL-операторы манипулирования данными и некоторые мощные расширения, в том числе конструкции IF ... THEN ... ELSE, WHILE ... DO, FOR SELECT ... DO, определенные в системе исключения, обработку ошибок и события.

Хранимые процедуры могут быть вызваны из приложений с использованием динамических операторов SQL. Они также могут быть вызваны интерактивно из isql и из многих других инструментов работы с базами данных, рекомендованных для использования с Firebird. Исполняемые модули, включая вложенные процедуры, могут быть использованы в скриптах с тем ограничением, что все входные параметры являются константами и не существует выходных наборов. В скриптах не существует возможности передавать переменные параметры.

Выполняемые хранимые процедуры

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

Хранимые процедуры выбора

Хранимые процедуры выбора названы так, потому что они написаны с использованием некоторых специальных расширений языка для создания многострочных выходных наборов, возвращающихся вызвавшей программе, которая использовала запрос SELECT - "виртуальные таблицы".

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

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

В вашем скрипте или в isql начните с установки символа терминатора, который будет использован для отметки конца синтаксиса CREATE PROCEDURE. Следующий пример устанавливает символ терминатора в &:

SET TERM &;

Синтаксис оператора:

CREATE PROCEDURE имя-процедуры

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

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

AS

< тело -процедуры>

<тело-процедуры> =

[DECLARE [VARIABLE] переменная тип-данных;

[...]]]

BEGIN

<составной-оператор>;

END <терминатор>

Элементы заголовка

Объявляйте в заголовке:

* имя процедуры, которое обязательно и должно быть уникальным в базе данных, например:

CREATE PROCEDURE MyProc

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

CREATE PROCEDURE MyProc (invarl integer, invar2 date)

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

данных. Не требуется соответствия имен входных аргументов именам параметров в вызывающей программе;

* любые необязательные выходные параметры (аргументы), требуемые в процедуре, с их типами данных. Список следует за ключевым словом RETURNS. список заключается в скобки, параметры отделяются друг от друга запятыми, например: