Хелен Борри - Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Название:Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Автор:
- Жанр:
- Издательство:БХВ-Петербург
- Год:2006
- Город:Санкт-Петербург
- ISBN:5-94157-609-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хелен Борри - Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ краткое содержание
Рассмотрены вопросы, необходимые разработчику для создания клиент-серверных приложений с использованием СУБД Firebird, явившейся развитием СУБД Borland Interbase 6. Содержится обзор концепций и моделей архитектуры клиент/сервер, а также практические рекомендации по работе с клиентскими библиотеками Firebird. Детально описаны особенности типов данных SQL, язык манипулирования данными (Data Manipulation Language, DML), а также синтаксис и операторы языка определения данных ( Data Definition Language, DDL). Большое внимание уделено описанию транзакций и приведены советы по их использованию при разработке приложений. Описано программирование на стороне клиента и сервера написание триггеров и хранимых процедур, создание и использование событий базы данных, обработка ошибок в коде на сервере и многое другое. Материал сопровождается многочисленными примерами, советами и практическими рекомендациями.
Для разработчиков баз данных
Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Использование (вызов) выполняемых процедур
Выполняемая процедура вызывается оператором EXECUTE PROCEDURE. Она может возвращать не более одной выходной строки. Для выполнения хранимой процедуры в isql используйте следующий синтаксис:
EXECUTE PROCEDURE ИМЯ [(] [ аргумент [, аргумент . . . ] ] [) ] ;
Имя процедуры должно быть задано.
Правила, касающиеся аргументов, следующие:
* значения должны быть заданы для всех входных аргументов;
* если есть несколько входных аргументов, они должны отделяться друг от друга запятыми;
* каждый аргумент является константой, выражением, преобразуемым в константу или заменяемым параметром;
* переменные могут передаваться как входные аргументы только внутри модуля PSQL;
* заменяемые параметры могут передаваться только внешним операторам DSQL;
* константы и выражения, которые преобразуются в константы, являются допустимыми для любого вызова;
* выражения, которые оперируют с переменными или заменяемыми параметрами, недопустимы;
* скобки, заключающие список аргументов, необязательны.
Поскольку наша процедура DELETE_EMPLOYEE не возвращает аргументов, синтаксис ее вызова из клиентского приложения и из другой процедуры одинаков:
EXECUTE PROCEDURE DELETE_EMPLOYEE (29) ;
При этом, когда процедура вызывается из другой процедуры, входные аргументы могут быть (и обычно бывают) представлены переменными. Поскольку EXECUTE PROCEDURE является оператором DSQL, синтаксис требует, чтобы имя переменной имело префикс точку с запятой:
EXECUTE PROCEDURE DELETE_EMPLOYEE (:EMP_NUMBER);
Другая процедура ADD_EMP_PROJ получает два входных аргумента, ключ служащего и проекта соответственно. Пример вызова может быть таким:
EXECUTE PROCEDURE ADD_EMP_PROJ (32, 'MKTPR');
Заменяемые параметры используются для входных аргументов при вызове этой процедуры из клиентского приложения:
EXECUTE PROCEDURE ADD_EMP_PROJ (?, ?) ;
Если выходному параметру не было определено значение, то его значение непредсказуемо, и это может привести к ошибке, иногда достаточной для нарушения целостности данных. В процедуре следует обеспечить инициализацию всех выходных параметров значениями по умолчанию, до того как нужные значения получатся в процессе обработки и будут выданы при выполнении операторов SUSPEND и EXIT.
В процедурах выбора и в выполняемых процедурах оператор EXIT приводит к немедленному переходу к финальному оператору END без выполнения других операторов.
Что произойдет, если процедура достигнет финального оператора END, зависит от ее типа.
* В процедуре SELECT код SQLCODE будет установлен в 100 для указания того, что больше нет найденных строк, а управление перейдет вызвавшей программе.
* В выполняемой процедуре управление перейдет к вызвавшей программе с передачей ей выходных значений, если они присутствуют. Вызовы из триггеров или процедур получают выходные данные через переменные, как задано в RETURNING_VALUES. Приложение получает их в структуре записи.
В выполняемых процедурах SUSPEND имеет точно такой эффект, что и END.
Рекурсивные процедуры
Если процедура вызывает саму себя, она является рекурсивной. Рекурсивные процедуры полезны для задач, включающих повторяющиеся шаги.
Каждое обращение к процедуре называется экземпляром (instance), поскольку каждое обращение к процедуре является отдельной сущностью, которая выполняется так же, как если бы она была вызвана из приложения; она резервирует память и стек с учетом требований выполнения ее задач.
Хранимые процедуры могут иметь глубину вложений не более 1000. Такое ограничение помогает предотвратить бесконечные циклы, которые могут появиться, если в процедуре не задано условие завершения цикла. Однако ограничения памяти и размера стека могут сделать количество вложенных уровней меньше 1000.
Процедура DEPT_BUDGET в примере базы данных EMPLOYEE иллюстрирует работу рекурсивной процедуры. Она принимает в качестве входа код DNO, эквивалентный коду DEPT_NO - ключу таблицы DEPARTMENT. Таблица DEPARTMENT имеет многоуровневую древовидную структуру: каждый отдел, не являющийся головным отделом, имеет внешний ключ HEAD_DEPT, ссылающийся на DEPT_NO своего непосредственного "родителя".
Процедура обращается к таблице DEPARTMENT по этому полученному ключу. Она сохраняет значение BUDGET этой строки в выходной переменной тот. Она также выполняет подсчет количества отделов, непосредственно предшествующих данному отделу в структуре отделов. Если нет подотделов, оператор EXIT осуществляет переход сразу на финальный оператор END ^. Текущее значение тот становится выходом процедуры, и процедура завершается.
SET TERM ^;
CREATE PROCEDURE DEPT_BUDGET (
DNO CHAR(3) )
RETURNS (
TOT DECIMAL(12,2) )
AS
DECLARE VARIABLE sumb DECIMAL(12, 2);
DECLARE VARIABLE rdno CHAR(3);
DECLARE VARIABLE cnt INTEGER;
BEGIN
tot = 0;
SELECT budget FROM department WHERE dept_no = :dno INTO :tot;
SELECT count(budget) FROM department WHERE head_dept = :dno INTO :cnt;
IF (cnt = 0) THEN
EXIT;
Если существуют подотделы, то выполнение продолжается. Входной код DNO используется в предложении WHERE курсора FOR ... SELECT (см. разд. "Курсоры в PSQL") для выделения по очереди каждой строки из таблицы DEPARTMENT, которая содержит в коде HEAD_DEPT то же значение, что и в DNO, и помещения значение из DEPT_NO этой строки в локальную переменную RDNO:
FOR SELECT dept_no FROM department
WHERE head_dept = :dno
INTO :rdno DO
BEGIN
Эта локальная переменная теперь становится входным кодом для рекурсивного вызова процедуры. При каждой рекурсии выходное значение тот увеличивается на значение возвращаемого бюджета, пока не будут обработаны все соответствующие строки:
EXECUTE PROCEDURE dept_budget :rdno RETURNING_VALUES :sumb;
tot = tot + sumb;
END
Под конец возвращаемое значение, аккумулированное в рекурсиях, передается вызвавшей программе, и процедура завершается:
EXIT; /* оператор EXIT необязателен */
END^
COMMIT^
На этот раз наша процедура имеет входные параметры. Наш простой вызов в DSQL может выглядеть следующим образом:
EXECUTE PROCEDURE DEPT BUDGET ('600');
Или же мы можем использовать заменяемый параметр:
EXECUTE PROCEDURE DEPT_BUDGET (?);
Курсоры в PSQL
Курсоры состоят из трех основных элементов:
* набора строк, определенных выражением SELECT;
* указателя, который перемещается через набор от первой строки к последней, изолируя строку для некоторого вида деятельности;
* набора переменных- определенных как локальные переменные, выходные аргументы или и те, и другие, - для получения значения столбцов, возвращаемых каждой строкой при ссылке на них указателя.
Проход указателя через набор может рассматриваться как операция "цикла". Операции, выполняющиеся в процессе этого "цикла", когда указатель ссылается на строку, могут быть простыми или сложными.
PSQL имеет две реализации курсора, одна хорошо известная, а другая не была ранее документирована.
Читать дальшеИнтервал:
Закладка: