Реляционный подход, позволяющий использовать одно выражение для манипуляции множеством строк в таблице, является более прогрессивным по сравнению с пошаговыми (одна запись за раз) методами манипуляции данными традиционных языков. Однако, поскольку предполагается, что SQL будет использоваться в больших организациях, где используются и традиционные языки обработки данных, то необходим метод, позволяющий интегрировать SQL-выражения в программы, написанные на традиционных языках. Таким методом является встроенный SQL.
Во встроенном SQL есть набор выражений, используемых для встраивания SQL-выражений в программы, написанные на таких языках, как Кобол, Си и Паскаль (базовые языки). Эти выражения являются флагами, сообщающими препроцессору, что последующие за ними части программы должны быть заменены вызовом подпрограммы СУБД. Среди этих выражений имеются также специальные средства, называемые курсорами, позволяющие пошаговую обработку результатов выполнения запросов SQL.
Встроенный SQL. Набор выражений, позволяющих использовать SQL совместно с традиционными языками программирования.
Базовый язык. Язык программ, в которые можно погружать SQL-выражения.
Приведем пример встроенной SQL-программы:
ЕХЕС SQL
DECLARE WORK_ASGNMNT CURSOR
FOR
SELECT *
FROM ASSIGNMENT
WHERE WORKER_ID = REQUESTED – WORKER_ID
END ЕХЕС
Эта программа может быть встроена в программу, написанную на Коболе в качестве базового языка. Первая строка (ЕХЕС SQL) и последняя строка (END EXEC) - выражения-флаги; они означают, что строки между ними - SQL-программа. Программа на Коболе, содержащая эту SQL-программу, перед компиляцией будет обработана компилятором предварительного прохода. Компилятор предварительного прохода распознает выражения-флаги и заменяет их CALL-выражениями — вызовами подпрограмм СУБД, которые во время выполнения будут обрабатывать эту SQL-программу. Когда программа на Коболе компилируется, компилятор игнорирует SQL CALL-выражения и компилирует всю остальную программу.
|
Выражения-флаги. Выражения SQL, встроенные в прикладную программу, сообщающие о начале или конце последовательности SQL-выражений.
Остальная часть нашего примера содержит выражение DECLARE CURSOR, определяющее курсор. Курсор - это разновидность файла, содержимое которого создается во время исполнения программы. Обратите внимание, что в определении курсора участвует выражение SELECT. Фраза WHERE ссылается на столбец таблицы ASSIGNMENT (WORKER_ID) и означает, что строка должна быть выбрана, если значение WORKER_ID равно значению переменной в программе на Коболе (REQUESTED-WORKER-ID).
Никакие данные не будут выбраны до тех пор, пока курсор не будет открыт отдельной командой. Команда «открыть курсор»:
OPEN WORK_ASGNMNT
заставит СУБД выполнить SELECT-выражение, Отдельные строки, помещенные в курсор в процессе выполнения команды OPEN, можно извлекать при помощи команды FETCH, аналогичной команде READ (читать). Для обновления и удаления данных таблиц базы данных существуют другие команды. Команда CLOSE (закрыть) удаляет данные из курсора, так что его можно снова открыть командой OPEN и получить новые данные, отражающие текущее состояние базы данных.
Курсор. Средство погруженного SQL хранения результатов SQL-запроса для дальнейшей обработки.
Команда OPEN (открыть курсор). Выражение погруженного SQL, заставляющее СУБД обработать запрос курсора и записать результат в курсор.
|
Команда FETCH (извлечь). Команда, извлекающая одну строку из открытого курсора.
11. Определение представлений данных
Ранее в этой главе мы показали, как в схеме базы данных определяются таблицы. Эти таблицы называются базовыми, поскольку они содержат основные данные базы данных. Части этого набора базовых таблиц, а также выведенную из них информацию, можно определять в представлениях базы данных, которые также определяются в схеме базы данных.
Базовая таблица. Таблица, содержащая основные или действительные данные.
Представление данных - это окно, через которое видна часть базы данных. Представления данных полезны для поддержания конфиденциальности путем ограничения доступа к определенным частям базы данных и для упрощения выполнения часто используемых запросов. Например, для того чтобы сохранить конфиденциальность, мы можем создать представление данных, показывающее всю информацию о работнике, кроме его ставки.
Представление данных. Определение ограниченной части базы данных.
CREATE VIEW B_WORKER AS
SELECT WORKER_ID, WORKER_NAME, SKILL_TYPE, SUPV_ID
FROM WORKER
B_WORKER в нашем примере - это имя вновь созданного представления данных. За именем представления данных может следовать перечисление имен столбцов представления данных, заключенное в скобки. В нашем случае мы опустили имена столбцов, так что имена столбцов будут просто унаследованы из таблицы, откуда они взяты. Часть выражения после слова AS называется спецификациейзапроса. В качестве спецификации может использоваться любой правильно сформулированный запрос.
|
Спецификация запроса. Определение запроса, используемого в определении представления данных, курсора или в другой команде.
Система на самом деле не создает значения данных для B_WORKER до тех пор, пока к нему не обращаются. В этот момент спецификация запроса выполняется, создавая B_WORKER из данных таблицы WORKER, существующих в момент выполнения. Таким образом, данные представления динамически обновляются с изменением данных соответствующих таблиц базы данных.
Предположим, что нас часто интересует информация об электриках: здания, на которых они назначены работать, и дата начала работы. Тогда нам подойдет такое представление данных:
CREATE VIEW ELEC_ASSIGNMENT AS
SELECT WORKER ID, BLDG_ID, START_DATE
FROM WORKER, ASSIGNMENT
WHERE SKILL_TYPE = 'Электрик' AND
WORKER.WORKER_ID = ASSIGNMENT.WORKER_ID
При обращении к представлению данных ELEC_ASSIGNMENT СУБД сначала породит значения его данных. В нашей базе данных ELEC_ASSIGNMENT (ЭЛЕК_РАБОТА) будет выглядеть следующим образом:
ELEC_A3SIGNMENT
WORKER _NAME BLDG_ID START_DATE
К.Фарадей 312 10.10
К.Фарадей 515 17.10
Х.Колумб 435 08.10
Х.Колумб 460 23.10
В запросах можно использовать представления данных. Предположим, что нас интересуют электрики, работающие на здании 435.
Запрос: Кто из электриков назначен на здание 435 и. когда он должен начать работу?
SELECT WORKER_NAME, START_DATE
FROM ELEC_ASSIGNMENT
WHERE BLDG_ID = 435
Результат: X.Колумб 10.08
Система сначала создала представленную выше таблицу, а затем применила к ней запрос.
Мы также можем при определении представления данных использовать операцию группировки. Рассмотрим встречавшийся ранее запрос, определяющий для каждого менеджера сумму максимальной ставки его подчиненных
CREATE VIEW MAX_WAGE (SUPV_ID, MAX_HRLY_RATE) AS
SELECT SUPV_ID, MAX(HRLY_RATE)
FROM WORKER
GROUP BY SUPV_ID
Обратите внимание, что в этом примере мы включили в определение имена столбцов представления данных. Они следуют непосредственно за именем представления данных MAX_WAGE (MAKC_CTABKA). В этом случае имена столбцов нужно обязательно включать, так как один из столбцов - результат вычисления встроенной функции, и для него нет имени, которое он мог бы унаследовать.
Мы можем обращаться с запросом к этому представлению данных, чтобы определить, у кого имеются подчиненные, чья ставка превышает заданную сумму.
Запрос: У кого есть подчиненные, чья ставка превышает 12 долларов?
SELECT SUPV_ID
FROM MAX_WAGE
WHERE MAX_HRLY_RATE > 12
Обрабатывая этот запрос, система сначала выполнит спецификацию запроса представления данных и создаст такую таблицу:
SUPV ID MAX_HRLY_RATE
1311 15.50
1520 13.75
2920 10.00
3231 17.40
Затем она применит сам запрос. В результате получится
SUPV_ID