Delphi 3. Библиотека программиста

       

Применение иерархических данных в запросах


Возможности иерархических и реляционных моделей по части запросов сильно расходятся. Реляционная модель хорошо подходит для поиска записей по атрибутам (полям) или объединения таблиц по общим значениям. На SQL такие запросы часто записываются в виде коротких, очевидных выражений.

Однако SQL плохо подходит для описания концепций типа «найти где-то среди потомков объект с зеленым маркером». Возможно, SQL без проблем найдет зеленый маркер, но при этом он понятия не имеет, что такое «потомки объекта». В разделе этой главы, посвященном SQL (см. ниже), приведены некоторые возможные варианты итерационного поиска записей, но, если иерархия находится в памяти, можно получить список потомков в виде набора идентификаторов и использовать его в критерии запроса типа IN. Запрос будет искать значение поля в ограниченном списке вариантов. В листинге13.5 показано, как SQL-запрос создается программой в свойстве TQuery.SQL. При этом SQL выполняет лишь часть работы; сначала иерархический объект вычисляет потомков, пользуясь своими собственными средствами.

Листинг 13.5. Использование SQL для поиска среди потомков

procedure TForm1.FindColoredBoxes (ColorName : String; StartingID : Integer); var DescendantString : String; begin DescendantString := HierarchyObject.GetDescendants(StartingID); with Query1 do begin DisableControls; Close; with SQL do begin Clear; Add('SELECT *'); Add('FROM BoxList T1'); Add('WHERE T1.BoxColor = "' + ColorName + '"'); { Предполагается, что идентификаторы в DescendantString разделяются запятыми } if DescendantString <> '' then Add('AND T1.BoxID IN (' + DescendantString ')'); end; Open; EnableControls; end; end;

Пример: если вас интересуют художники всех специализаций, можно найти в иерархии родителя всех художников, на программном уровне получить идентификаторы всех потомков этого объекта и использовать их в критерии. Запись однозначно определяется по ее идентификатору, каким бы специали зированным он ни был. Когда вам потребуется выбрать общую категорию, данная запись будет извлечена среди прочих. Благодаря иерархической структуре данных вам даже не нужно знать, сколько потомков имеет объект «Художник» — вы автоматически получаете их все.

Если иерархия представлена компонентом TOutline или TTreeView, вы можете воспользоваться навигационными средствами этих компонентов для перебора потомков любого объекта. В противном случае объект придется загружать в память и установить связи-указатели между родителями и детьми или же воспользоваться итерационными или рекурсивными методиками, описываемыми ниже.



Содержание раздела