Конструкция where |
Конструкция where позволяет связать таблицы и дает возможность ограничить записи, включаемые в логическую таблицу, теми записями, которые удовлетворяют определенным критериям. Данные критерии называются фильтрами. Фильтр представляет собой логическое выражение.
<конструкция-where> = where (( <условия-подцепки> )) [ and ( <фильтр> ) ] | { <фильтр> }
Круглые скобки для фильтров не обязательны.
Ключевое слово where - начинает конструкцию. Конструкция where может содержать либо условия подцепки (возможно с фильтрами), либо просто фильтры, которые накладывают ограничения на записи (кортежи), используемые в логической таблице. Фильтр конструкции where накладывает ограничения на все узлы данной логической таблицы (выборки).
Для привязки фильтра к определенному узлу логической таблицы необходимо поместить фильтр после любой подцепки, соответствующей одному из сегментов ключа этой узловой таблицы (см. ниже).
<условия-подцепки> - Условия подцепки представляют собой полный для данной логической таблицы набор соединений таблиц (подцепок), разделенных ключевым словом and. Порядок перечисления сегментов не имеет значения.Условия подцепки помещаются в двойные круглые скобки.
Начиная с Атлантис 5.4.23 если в пределах одного ограничения встретятся две или более подцепки 1:1 к вычислямому выражению (не к root) одной и той же таблицы по одному и тому же полю, то на стадии компиляции будет выдано предупреждение "Узел уже подцеплен на == по этому полю в этом ограничении", т.к. считается что имеет смысл только однозначная подцепка по уникальному индексу.
<условия-подцепки> = <подцепка> [ and ( <фильтр> ) ] { and <подцепка> [ and ( <фильтр> ) ] }
<подцепка> - каждая подцепка устанавливает соответствие между отдельным полем подчиненной таблицы и полями родительских таблиц. Подцепка косвенным образом определяет индекс, который подбирается драйвером базы данных из числа описанных в словаре.
<подцепка> = root <условие-связи-root> <поле-подчиненной-таблицы> [ <атрибуты-индекса> ] | <выражение> <условие-связи> <поле-подчиненной-таблицы> [ <атрибуты-индекса> ]
root - если рассматриваемый узел (физическая таблица) не имеет родительских таблиц, т.е. является корневым узлом, то слева от условия связи задается ключевое слово root, а справа - поле корневого узла. В подобном случае конструкция <подцепка> используется не для связывания таблиц, а для установки фильтра на корневой узел.
<условие-связи-root> - для корневого узла допустимы мягкая и жесткая подцепки.
Реляционные связи могут быть двух типов - жесткие и мягкие. При мягкой подцепке отсутствующие в подчиненной таблице записи заполняются значениями по умолчанию. При жесткой подцепке записи родительской таблицы, для которых не были найдены записи в таблицах-потомках, в выборку не попадают. Отличаются также связи по уникальному и неуникальному индексу. Для мягко подцепленных таблиц существует оптимизация: первая запись выбирается только при обращении к какому-либо полю из этой таблицы.
Условие "==" соответствует мягкой подцепке, условие "/==" - жесткой подцепке.
<условие-связи-root> = == | /==
<условие-связи> - для некорневых узлов кроме мягкой и жесткой подцепок используются связи с неравенствами:
<условие-связи> = == | /== | >>= | <<= | >> | <<
<поле-подчиненной-таблицы> - поле подцепляемой таблицы, по которому осуществляется связь:
<поле-подчиненной-таблицы> = <имя-таблицы>.<имя-поля>
<атрибуты-индекса> - перечень атрибутов, заключенный в скобки. По умолчанию для обработки подцепки берется первый подходящий индекс (индекс, содержащий подцепляемые поля). Данные атрибуты позволяют задать дополнительные требования к выбираемому индексу. Необходимо помнить, что условия связи проверяются не на полях таблице, а на выбранном индексе, с учетом атрибутов offset и length. Атрибуты в списке перечисляются через запятую:
<атрибуты-индекса> = ( <атрибут> [, <атрибут> ] )
<атрибут> - атрибут индекса:
<атрибут> = noIndex | desc | length = <целое-число> | offset = <целое-число>
noIndex - не использовать индекс при обработке данной подцепки.
desc - сортировать по убыванию поля подчиненной таблицы.
Атрибут offset задает позицию, начиная с которой значение поля воспринимается как значение сегмента.
По умолчанию смещение сегмента считается равным нулю.
Если для сегмента типа string задано ненулевое смещение, то в сегмент включается length знаков, начиная со смещения offset без учета конца строки. Таким образом, если атрибут length не задан или задан некорректно, то в сегмент попадают случайные данные ("мусор").
Атрибут length (l) устанавливает значимую длину сегмента ключа, равную целому числу без знака.
Начало сегмента совпадает с началом поля, если не задано смещение сегмента.
Используется для полей типа string и char.
По умолчанию длина сегмента приравнивается к длине поля.
<выражение> - слева от условия связи задаются выражения, которые могут содержать поля родительских таблиц и константы.
<фильтр> - каждая подцепка может иметь собственный фильтр, который присоединяется к подцепке также ключевым словом and. Подобные фильтры называются узловыми.
Для привязки фильтра к некоторому узлу логической таблицы необходимо указать фильтр после любой подцепки, соответствующей одному из сегментов ключа этой узловой таблицы. Узловое условие проверяется при выборке записей из того узла, к которому это условие привязано, и не накладывает ограничений на остальные узлы логической таблицы.
В данном примере в выборку включаются все сотрудники, работающие не на постоянной основе. Для каждого сотрудника выбирается его отдел и должность, причем сотрудники, для которых должность не задана, в выборку не включаются в силу жесткой подцепки таблицы Post. Кроме того, для каждого сотрудника выбираются все проекты, в которых он принимает участие (таблица Empproj - связь сотрудников и проектов). Для каждого проекта выбираются его этапы (таблица Stage). Для каждого этапа выбираются затраты на этап в диапазоне от bDate до eDate.
create view bigView var bDate,eDate : date; as select * from Employee, Synonym Employee Chief, Department, Post, Project, Expens, ExClass, Stage where(( root == Employee.code and ( Employee.status <> 'П' ) and Employee.department == Department.code and Department.chief == Chief.code and Employee.post /== Post.code and Employee.project == EmpProj.employee and Employee.project == Project.code and Project.stage == Stage.project and Project.code == Expens.project and Stage.num == Expens.stage and bDate <<= Expens.exDate and eDate >>= Expens.exDate and Expens.exClass == ExClass.code ));
Начиная с Атлантис 5.4.23 добавлен контроль подцепок 1:1 по одному и тому же полю.