Чтение онлайн

на главную - закладки

Жанры

Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Борри Хелен

Шрифт:

В любых многотабличных операциях сервер Firebird поддерживает один внутренний курсор для каждого потока. В предыдущих примерах соединений таблиц TableA и TableB каждая имеет свой курсор. Когда появляется соответствие, сервер создает объединенный образ для выходного потока, копируя потоки с текущего адреса из двух курсоров, как показано на рис. 22.5.

Реентерабельные соединения

Условия проектирования иногда требуют формирования объединенного набора из двух или более потоков, которые поступают из одной и той же таблицы. Часто таблица проектируется с иерархической,

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

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

Курсоры для реентерабельных соединений

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

В следующем примере каждое подразделение организации хранится с родительским идентификатором, который указывает на первичный ключ его руководящего подразделения. Приведенный далее запрос трактует подразделения и родительские подразделения, как если бы они были двумя таблицами:

SELECT

D1.XD,

D1.PARENTID,

D1.DESCRIPTION AS DEPARTMENT,

D2.DESCRIPTION AS PARENT_DEPT

FROM DEPARTMENT D1

LEFT JOIN DEPARTMENT D2

/* левое соединение обращается к корню дерева, ID 100 */

ON Dl.PARENTID = D2.ID;

На рис. 22.6 проиллюстрировано, как выбираются записи потомков в реентерабельном обращении к таблице DEPARTMENT.

Рис. 22.6. Внутренние курсоры для простого реентерабельного соединения Простой двухуровневый результат показан на рис. 22.7.

Результат этого запроса очень простой - одноуровневая денормализация. Операции получения древовидного результата для таблиц такого вида часто являются рекурсивными, они используют хранимые процедуры для реализации и управления рекурсией [79] .

Рис. 22.7. Результат простого реентерабельного соединения

Подзапросы

Подзапрос - это специальный вид выражения, которое фактически является запросом SELECT к другой таблице, включенным в спецификацию

основного запроса. Выражение включенного запроса называют подзапросом, вложенным запросом, встроенным запросом, а иногда (ошибочно) Sub-SELECT.

79

В "SQL for Smarties" Joe Celco предлагает интересные решения для хранения и поддержки древовидных структур в реляционных базах данных (Morgan Kaufmann, 1999).

В Firebird версии 1.5 и выше выражения подзапроса используются тремя способами:

* для получения одной строки или многострочного входного набора для операции INSERT (его синтаксис описан в разд. "Оператор INSERT" главы 20);

* для задания в процессе выполнения выходного столбца только для чтения для запроса SELECT;

* для получения значений или условий для предикатов поиска.

В версиях Firebird после 1.5 появляется четвертый вариант подзапросов- виртуальная таблица, который кратко обсуждается в главе 24.

Задание столбца при использовании подзапроса

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

Вложенный запрос всегда должен иметь условие в предложении WHERE для ограничения вывода одним столбцом из одной строки (называется скалярным запросом); иначе вы увидите подобное сообщение об ошибке: "Multiple rows in singleton select" (Запрос, который должен вернуть одну строку, вернул множество строк).

Следующий запрос использует подзапрос для получения выходного столбца.

SELECT

LAST_NAME,

FIRST_NAME,

ADDRESS1,

ADDRESS2,

POSTCODE,

(SELECT START_TIME FROM ROUTES

WHERE POSTCODE = '2261' AND DOW = 'MONDAY') AS START_TIME

FROM MEMBERSHIP

WHERE POSTCODE = '2261';

Этот подзапрос указывает одно значение POSTCODE для получения значения поля START_TIME транспортного маршрута (таблица ROUTES). Столбцы POSTCODE в главном запросе и в подзапросе могут быть заменены параметрами. Чтобы сделать запрос более общим и более полезным, мы можем использовать коррелированные подзапросы.

Коррелированные подзапросы

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

В следующем примере связываемые столбцы в главном запросе и в подзапросе являются коррелированными; здесь использованы алиасы таблиц для устранения какой- либо неясности:

SELECT

M.LAST_NAME,

M.FIRST_NAME,

M.ADDRESS1,

M.ADDRESS2,

M.POSTCODE,

(SELECT R.START_TIME FROM ROUTES R

WHERE R.POSTCODE = M.POSTCODE AND M.DOW = 'MONDAY') AS START_TIME

FROM MEMBERSHIP M

WHERE . . .

Этот запрос возвращает одну строку для каждого выбранного элемента, независимо от того, существует ли соответствие между полями POSTCODE обеих таблиц. Если нет соответствия, то поле START_TIME будет иметь значение NULL.

Поделиться:
Популярные книги

Бастард Императора. Том 3

Орлов Андрей Юрьевич
3. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 3

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Эволюционер из трущоб. Том 3

Панарин Антон
3. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
6.00
рейтинг книги
Эволюционер из трущоб. Том 3

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Адвокат Империи 2

Карелин Сергей Витальевич
2. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 2

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Котенок. Книга 3

Федин Андрей Анатольевич
3. Котенок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Котенок. Книга 3

Империя Хоста 3

Дмитрий
3. Империя Хоста
Фантастика:
боевая фантастика
попаданцы
5.50
рейтинг книги
Империя Хоста 3

Кодекс Крови. Книга I

Борзых М.
1. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга I

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Воспитание бабочек

Карризи Донато
Детективы:
триллеры
прочие детективы
5.00
рейтинг книги
Воспитание бабочек

Никчёмная Наследница

Кат Зозо
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Никчёмная Наследница

Имперский Курьер. Том 3

Бо Вова
3. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 3