Программирование >>  Sql: полное руководство 

1 ... 68 69 70 [ 71 ] 72 73 74 ... 264


Стандарт SQLl и большинство коммерческих СУБД предоставляют весьма ограниченные возможности для манипулирования записями и группами записей. SQLl допускает только добавление записей в таблицы, а также их выборку, обновление или удаление (с помощью инструкций select, update и delete).

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

Конструктор записи

В стандарт SQL2 включена специальная конструкция, предназначенная для определения строк данных, - конструктор записи (рис. 9.13). В своей наиболее распространенной форме это просто разделенный запятыми список литералов или скалярных выражений. Вот, например, конструктор для строки данных, структура которой соответствует структуре таблицы offices;

(23, San Diego, Western, NULL, DEFAULT, 0.00)

скалярнов выражение --

NULL-

-DEFAULT --J-

. скалярное выражение - -

NULL-

-DEFAULT-

- подчиненный запрос, возвращающий запись -

Нарамма конструк!

Рис. 9.13.

Результатом этого выражения является одна строка данных с шестью столбцами. Четвертый столбец результирующей строки должен содержать значение null. Ключевое слово default в пятой позиции указывает на то, что пятый столбец должен содержать значение, присваиваемое этому столбцу по умолчанию. Названное ключевое слово может встречаться только в определенных ситуациях - например, когда конструктор записи включается в инструкцию insert, вследствие чего генерируемая им запись добавляется в таблицу.

Если конструктор записи находится в предложении where, в нем могут использоваться имена столбцов (в качестве отдельных элементов данных или в составе выражений). Для примера рассмотрим такой запрос:

Перечислить номера заказов на изделие ACI41002 с указанием количества единиц товара и суммы сделки.



select order num, qty, amount from orders where (mfr, product) = (aci, 41002)

При выполнении этого запроса предложение where по очереди применяется к каждой строке таблицы orders. Первый констр) тор в этом предложении (слева от знака равенства) генерирует строку из двух столбцов, содержащую идентификаторы производителя и товара для текущего обрабатываемого заказа. Второй конструктор (справа от знака равенства) генерирует строку из двух столбцов, содержащую лите-рально заданные идентификатор производителя ACI и идентификатор товара 41002. Далее оператор = сравнивает две записи (заметьте, не скалярные значения!). Стандартом SQL2 определено, что оператор сравнения записей по очереди сравнивает пары значений каждого столбца. Результатом сравнения является значение true только в том случае, если все попарные сравнения вернули true. Конечно, тот же запрос можно написать и без конструкторов:

select order num, qty, amount from orders

where (mfr = aci) and (product = 41002)

Для такого простого примера обе формы запроса одинаково удобны. А вот в случае более сложных запросов роль конструкторов записей очень важна, особенно когда в сравнении участвует результат подчиненного запроса

Подчиненные запросы, возвращающие записи

Как уже говорилось ранее в этой главе, стандарт SQL1 предусматривает возможность формулирования достаточно сложных запросов к базе данных с использованием механизма подчиненных запросов. Подчиненный запрос - это обычный запрос на выборку (т.е. инструкция select), но стандарт SQLl требует, чтобы он возвращал скалярное значение, т.е. только одно значениец.шных. Это значение участвует в одном из выражений в главной инструкции SQL, содержащей подчиненный запрос. Такая методика использования подчиненных запросов поддерживается всеми ведущими современными СУБД масштаба предприятия.

Стандарт SQL2 значительно расширяет возможности подчиненных запросов: теперь они могут генерировать не только одиночные значения, но и записи, которые могут участвовать в выражениях и сравниваться с другими записями. Для примера предположим, что нам требуется узнать номера и даты заказов самого дорогого товара. Логично начать с написания запроса, который находит идентификатор этого товара и его производителя:

Найти идентификатор самого дорогого товара и идентификатор его производителя.

select mfr id, proddct id from products

where price = (select max(price) from products)

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



Вывести номера и даты заказов самого дорогого товара.

SELECT ORDER NUM, ORDER DATE FROM ORDERS

WHERE (MFR, PRODUCT) = (SELECT MFR ID, PRODUCT ID

FROM PRODUCTS WHERE PRICE = (SELECT MAX(PRICE) FROM PRODUCTS))

Предложение where на самом верхнем уровне содержит оператор сравнения записей. Слева от него стоит конструктор записи, в котором указаны имена дву> столбцов. Каждый раз, когда проверяется это предложение, конструктор генерирует строку, состоящую из идентификатора производителя и идентификатора товара и; текущей записи таблицы orders. Справа от знака равенства стоит подчиненный запрос, который находит идентификационные данные для самого дорогого товара Результатом этого запроса тоже является строка, состоящая из двух столбцов с теми же типами данных, что и в строке слева от знака равенства.

Тот же запрос можно сформулировать и без помощи подчиненного запроса, возвращающего запись, но результат получится гораздо более громоздким:

SELECT ORDER NUM, ORDER DATE FROM ORDERS WHERE (MFR = (SELECT MFR ID

FROM PRODUCTS WHERE PRICE = (SELECT MAX(PRICE) FROM PRODUCTS)) )

AND (PRODUCT = (SELECT PRODUCT ID FROM PRODUCTS WHERE PRICE = (SELECT MAX(PRICE) FROM PRODUCTS)))

Вместо сравнения одной пары записей в предложении where нам пришлось выполнить два отдельных скалярных сравнения: одно - для идентификаторов производителей, а другое - для идентификаторов товаров. Из-за этого пришлось дважды выполнять практически один и тот же подчиненный запрос. Стоит ли говорить о том, что запрос с обработкой записей формулируется гораздо естественнее?

Сравнение записей

Чаще всего вьфзжения, генерирующие записи, используются в предложениях where и having в операции проверки на равенство, как в нескольких последних примерах. Сгенерированная запись (содержащая значения столбцов из строки, претендующей на включение в результаты запроса) сравнивается с другой записью (обычно с результатом подчиненного запроса или набором литеральных значений), и если эти записи совпадают, запись-кандидат включается в таблицу результатов запроса. Стандартом SQL2 предусмотрены и другие возможности сравнения записей: на неравенство и принадлежность определенному диапазону. При сравнении записей на неравенство в SQL2 используются те же правила, что и при обычной сортировке записей. Сначала сравнивавэтся первые столбцы двух записей, в случае их неравенства они используются для определения порядка записей. Если же они равны, сравниваются вторые столбцы двух записей и т.д. Вот результаты сравнения нескольких записей, составленных из трех столбцов, взятых из таблицы orders:

(ACI, 41002, 54) < (REI, 2A44R, 5)

- сортировка по первому столбцу



1 ... 68 69 70 [ 71 ] 72 73 74 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика