Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
BD / Урок 12-Рекурсивный SQL.doc
Скачиваний:
62
Добавлен:
20.02.2016
Размер:
721.41 Кб
Скачать

Фраза connectby

Фраза CONNECT BYпозволяет специфицировать связь между столбцами, формирующую иерархическое дерево. Она содержит условие, которое определяет древовидную связь. Условие может быть любым допустимым условием языка SQL, однако левая или правая часть условия должна содержать операторPRIOR, который указывает какая из строк выступает в качестве родительской. То есть условие в этой фразе должно иметь один из следующих видов:

PRIOR выражение_1 оператор_сравнения выражение_2

выражение_1 оператор-сравнения PRIOR выражение_2

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

Если вычисление дерева приводит к «зацикливанию», то это рассматривается как ошибочная ситуация. Зацикливание происходит в том случае, когда строка оказывается одновременно родительской (непосредственно или через несколько уровней) и дочерней (непосредственно или через несколько уровней) другой строки.

В приводимом ниже примере фраза CONNECT BYопределяет древовидную связь, в которой значение столбцаTchPKродительской строки должно быть равно значению столбцаChiefдочерней строки:

CONNECTBYPRIORTchPK=Chief

В следующем примере фразы CONNECT BYоператорPRIORприменяется только к значению столбцаTchPK. В связи с этим значениеTchPKвычисляется для родительской строки, а значенияChiefиSalaryдля дочерних:

CONNECT BY PRIOR TchPK = Chief AND Salary > 1000

Содержательно это следует трактовать следующим образом: соединять строки таким образом, чтобы TchPKродительской строки был равенChiefдочерней строки и у дочерней строки значение зарплаты было бы больше 1000.

Использование псевдостолбца level

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

При выполнении рекурсивного предложения SELECTстановится доступным псевдостолбец под именемLEVEL. Для каждой строки, формируемой рекурсивным запросом, псевдостолбецLEVELвозвращает значение 1 для корневой вершины, значение 2 для всех дочерних вершин корневой вершины, и т.д. На рис. 10.4 показывается древовидная структура таблицы с ее значениями столбцаLEVEL.

Рис.10.4. Древовидная структура таблицы с указанием уровней.

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

SELECTLPAD(' ',2*(LEVEL-1)) ||NameAS"Фамилия",TchPKAS"Номер преп.",ChiefAS"Номер руков.",PostAS"Должность преп."FROM TEACHER START WITH Chief IS NULL CONNECT BY PRIOR TchPK = Chief;

Фамилия Номер преп. Номер руков. Должность преп. ----------------- ----------- ------------ --------------- Сидоров 16 профессор Радишевский 4 16 доцент Хоменко 2 4 преподаватель Витковский 1 2 ассистент Воробьев 3 4 ассистент Кузнецов 5 4 преподаватель Марченко 9 5 ассистент Заплатинский 6 16 доцент Козлитин 8 6 ассистент Лебедь 7 16 доцент Недоводеев 11 7 преподаватель Резник 10 16 профессор Ахромеев 13 профессор Наумов 14 доцент Дараганов 15 преподаватель

15 строк выбрано.

Функция LPADприводит к формированию пробелов, кратных уровню, на котором расположена строка. Такие пробелы, сцепленные с помощью оператора конкатенации (||) с именами служащих, приводят к отступу имен согласно подчинению преподавателей.

Обратите внимание, что корневой сегмент имеет значение NULLдляChief. Если бы для указания этого корня было бы принято решение указать 16 в качестве значения столбцаChief(таким образом мы как бы указали, что он является руководителем над самим собой), то рекурсивный запрос не был бы отработан, так как представленная таким образом иерархическая структура имела бы цикл. Как видим из ответа, у нас 4 преподавателя на верхнем уровне.