Хелен Борри - Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ"
Описание и краткое содержание "Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ" читать бесплатно онлайн.
Рассмотрены вопросы, необходимые разработчику для создания клиент-серверных приложений с использованием СУБД Firebird, явившейся развитием СУБД Borland Interbase 6. Содержится обзор концепций и моделей архитектуры клиент/сервер, а также практические рекомендации по работе с клиентскими библиотеками Firebird. Детально описаны особенности типов данных SQL, язык манипулирования данными (Data Manipulation Language, DML), а также синтаксис и операторы языка определения данных ( Data Definition Language, DDL). Большое внимание уделено описанию транзакций и приведены советы по их использованию при разработке приложений. Описано программирование на стороне клиента и сервера написание триггеров и хранимых процедур, создание и использование событий базы данных, обработка ошибок в коде на сервере и многое другое. Материал сопровождается многочисленными примерами, советами и практическими рекомендациями.
Для разработчиков баз данных
Техника
Техника извлечения и манипулирования данными выходного набора использует курсор для чтения по порядку каждой строки из оператора SELECT В предварительно объявленный набор переменных. Часто это могут быть выходные аргументы, куда помещаются значения столбцов, однако это могут быть и локальные переменные. Внутри цикла с переменными выполняются действия соответствующим образом: преобразовываются для вычислений, если необходимо, или используются как аргументы поиска для вложенных циклов, чтобы получать данные из других запросов. В конце цикла, когда все выходные аргументы получают конечные значения, оператор SUSPEND приводит к паузе в выполнении, пока этот набор передается в кэш строк. Выполнение возобновляется, когда вызывается следующая пересылка.
Как мы видели в предыдущем примере BREAKAPART, оператор SUSPEND является тем элементом, который заставляет процедуру передавать строку.
Конструкция FOR SELECT ... DO
Для поиска множества строк в процедуре мы используем конструкцию FOR SELECT ... DO. Ее синтаксис:
FOR
<выражение-выбора>
INTO <:переменная [, :переменная [, ...]] DO
<составной-оператор>;
<выражение-выбора> может быть любым запросом выбора, использующим соединения, объединения, просмотры, другие процедуры выбора, вызовы функций и т.д. в любой допустимой комбинации.
Оператор FOR SELECT отличается от стандартного оператора SELECT тем, что требует наличия переменных, в которые помещаются значения столбцов, и спецификации полей.
<составной-оператор> может быть одним оператором SUSPEND или блоком из двух или более операторов. <составной-оператор> может иметь вложенные составные операторы.
FOR SELECT ... DO является конструкцией цикла, которая отыскивает строку, заданную в <выражении-выбора>, и выполняет для каждой строки оператор или блок операторов, следующих после DO.
Предложение INTO <переменные> обязательно и должно быть последним[116].
Обработка в цикле
На рис. 30.2 проиллюстрированы типичные виды деятельности, которые могут выполняться внутри циклов для генерации выхода в хранимой процедуре выбора.
Рис. 30.2. Операции в процедуре выбора
В следующих примерах мы посмотрим на то, как комбинации операций в PSQL могут представить более интересную область SQL.
Простая процедура с вложенными операторами SELECT
Процедура выбора ORG_CHART, которая присутствует в примере базы данных employee, не получает входных аргументов. Она использует цикл FOR ... SELECT, чтобы строить набор из ссылающегося на себя соединения таблицы DEPARTMENT и передавать значения столбцов по одной строке за раз набору переменных - некоторые из них локальные, некоторые объявлены как выходные аргументы.
CREATE PROCEDURE ORG_CHART
RETURNS (
HEAD_DEPT CHAR(25),
DEPARTMENT CHAR(25),
MNGR_NAME CHAR (2 0),
TITLE CHAR(5),
EMP_CNT INTEGER )
AS
DECLARE VARIABLE mngr_no INTEGER;
DECLARE VARIABLE dno CHAR(3);
BEGIN
FOR SELECT h.department, d.department, d.mngr_no, d.dept_no
FROM department d
LEFT OUTER JOIN department h ON d.head_dept = h.dept_no
ORDER BY d.dept_no
INTO :head_dept, :department, :mngr_no, :dno
DO
Каждый раз, когда цикл обрабатывает строку, он помещает значение ключа (MNGR_NO) в локальную переменную MNGR_NO. ЕСЛИ эта переменная имеет пустое значение, процедура создает значения для выходных аргументов MNGR_NAME и TITLE. ЕСЛИ же эта переменная имеет значение, она передается как аргумент поиска вложенному запросу к таблице EMPLOYEE, уникально идентифицирующему строку и выделяющему имя и код работы менеджера отдела. Эти значения передаются остальным выходным аргументам.
BEGIN
IF (:mngr_no IS NULL) THEN
BEGIN
mngr_name = '--TBH--';
title = '' ;
END
ELSE
SELECT full_name, job_code
FROM employee
WHERE emp_no = :mngr_no
INTO :mngr_name, :title;
SELECT COUNT (emp_no)
FROM employee
WHERE dept_no = :dno
INTO :emp_cnt;
Когда присвоены все выходные значения для одной строки, оператор SUSPEND передает строку в кэш. Управление передается опять на начало цикла, когда выполнен следующий запрос на пересылку.
SUSPEND;
END
END^
COMMIT^
Обратите внимание, как аккуратно вложенный запрос обходит ту проблему, которую мы имели с подзапросами в DSQL- мы могли в подзапросе вернуть одно и только одно значение. Если нам нужно много значений, а логика левого соединения не работает, то нам пришлось бы использовать множество подзапросов с множеством наборов алиасов для выделения каждого значения из его курсора.
Вызов процедуры выбора
Синтаксис вызова процедуры выбора очень похож на синтаксис обращения к таблице или к просмотру. Единственным отличием является то, что процедура может иметь входные аргументы:
SELECT <список-столбцов> FROM имя ([аргумент [, аргумент ...]])
WHERE <условия-поиска>
ORDER BY <список-упорядочения>;
Имя процедуры должно быть задано.
Правила входных аргументов идентичны правилам для выполняемых процедур - см. ранее разд. "Значения входных аргументов".
<список-столбцов>- разделенный запятыми список из одного или более выходных параметров, возвращаемых процедурой, или * для выбора всех столбцов.
Выходной набор может быть ограничен условиями поиска в предложении WHERE и упорядочен с помощью предложения ORDER BY.
Вызов процедуры ORG_CHART
Эта процедура не имеет входных параметров, следовательно, вызов SELECT выглядит как простой выбор в таблице, а именно:
SELECT * FROM ORG_CHART;
Выбор агрегатных значений из процедур
В дополнение к получению значений из процедуры вы можете использовать агрегатные функции. Например, для использования нашей процедуры с целью отображения количества отделов применяйте следующий оператор:
SELECT COUNT (DEPARTMENT) FROM ORG_CHART;
Аналогично, для отображения с помощью ORG_CHART максимального и среднего количества служащих в каждом отделе используйте следующий оператор:
SELECT
MAX(EMP_CNT),
AVG(EMP_CNT)
FROM ORG CHART;
! ! !
СОВЕТ. Если процедура получит ошибку или исключение, агрегатные функции не вернут правильных значений, поскольку процедура завершается до обработки всех строк.
. ! .
Вложенные процедуры
Хранимая процедура сама может вызывать хранимую процедуру. Каждый раз, когда хранимая процедура вызывает другую хранимую процедуру, такой вызов называется вложенным, потому что он появляется в контексте предыдущего и все еще активного вызова первой процедуры. Хранимая процедура, вызываемая другой хранимой процедурой, называется вложенной процедурой.
Следующая процедура возвращает список пользователей, ролей и привилегированных объектов базы данных с их привилегиями SQL. Внутри процедуры два вложенных вызова другой процедуры. Необходимо начать с определения и подтверждения вложенной процедуры - иначе внешняя процедура выдаст ошибку при подтверждении. Вы всегда должны начинать с нижней части "цепочки" при создании процедур, использующих вложенные процедуры.
Приведенная далее вложенная процедура не выполняет операторов SQL[117]. Она просто берет непонятную константу из набора, используемого внутренне в Firebird для представления типов объектов, и возвращает строку, более осмысленную для человека:
SET TERM ^;
CREATE PROCEDURE SP_GET_TYPE (
IN_TYPE SMALLINT )
RETURNS (
STRING VARCHAR(7) )
AS
BEGIN
STRING = 'Unknown';
IF (IN_TYPE = 0) THEN STRING = 'Table';
IF (IN_TYPE = 1) THEN STRING = 'View';
IF (IN_TYPE = 2) THEN STRING = 'Trigger';
IF (IN_TYPE = 5) THEN STRING = 'Proc';
IF (IN_TYPE = 8) THEN STRING = 'User';
IF (IN_TYPE = 9) THEN STRING = 'Field';
IF (IN_TYPE = 13) THEN STRING = 'Role';
END^
COMMIT ^
Теперь о внешней процедуре. Запрашиваемая в ней таблица является системной таблицей RBD$USER_PRIVILEGES. Она использует множество техник манипулирования, включая вызовы внутренней SQL-функции CAST() и внешней функции RTRIMO из стандартной библиотеки внешних функций ib_udf для преобразования элементов CHAR(31) в VARCHAR(31). Мы это делаем, потому что собираемся выполнять конкатенацию некоторых из этих строк и нам не нужны конечные пробелы.
SET TERM ^;
CREATE PROCEDURE SP_PRIVILEGES
RETURNS (
Q_ROLE_NAME VARCHAR (31),
ROLE_OWNER VARCHAR(31),
USER_NAME VARCHAR(31),
Q_USER_TYPE VARCHAR(7),
W_GRANT_OPTION CHAR(1),
PRIVILEGE CHAR(6),
GRANTOR VARCHAR. (31),
QUALIFIED_OBJECT VARCHAR(63),
Q_OBJECT_TYPE VARCHAR(7) )
AS
DECLARE VARIABLE RELATION_NAME VARCHAR(31);
DECLARE VARIABLE FIELD_NAME VARCHAR(31);
DECLARE VARIABLE OWNER_NAME VARCHAR(31);
DECLARE VARIABLE ROLE_NAME VARCHAR(31);
DECLARE VARIABLE OBJECT_TYPE SMALLINT;
DECLARE VARIABLE USF,R_TYPE SMALLINT;
DECLARE VARIABLE GRANT_OPTION SMALLINT;
DECLARE VARIABLE IS?ROLE SMALLINT;
DECLARE VARIABLE IS_VIEW SMALLINT;
BEGIN
Вначале мы создадим цикл по таблице RBD$USER_PRIVILEGES, выделяя и направляя некоторые значения прямо в выходные аргументы, а другие в локальные переменные:
FOR SELECT
RTRIM(CAST(RDB$U3ER AS VARCHAR(31))),
RDS$USER_TYPE,
RTRIM (CAST (RDB$GRANTOR AS VARCHAR (31) ) ) ,
RTRIM (CAST (RDB$RELATION_NAME AS VARCHAR (31) )) , RTRIM(CAST(RDB$FIELD_NAME AS VARCHAR (31))) ,
RDB$OBJECT_TYPE,
RTRIM(CAST(RDB$PRIVILEGE AS VARCHAR(31))),
RDB $GRANT OPTION
FROM RDB$USER_PRIVILEGES
INTO : USER_NAME, :USER_TYPE, : GRANTOR, : RELATION_NAME,
FIELD_NAME, : OBJECT_TYPE, : PRIVILEGE, : GRANT_OPTION
Взяв текущее значение выходной переменной USER_NAME, мы обращаемся к RDB$ROLES для получения владельца роли и имени роли в случае, когда "пользователь" текущей строки фактически является ролью. Если же это не роль, то эти поля будут представлены на выходе в виде пунктира:
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ"
Книги похожие на "Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Хелен Борри - Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ"
Отзывы читателей о книге "Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ", комментарии и мнения людей о произведении.