- •20.7. Средства sql
- •20.8. Резюме
- •21.1. Введение
- •21.2. Некоторые аспекты технологам поддержки принятия решений
- •21.3. Проектирование базы данных поддержки принятия решений
- •21.5. Хранилища данных и магазины данных
- •21.6. Оперативная аналитическая обработка
- •21.7. Разработка данных
- •21.8. Резюме
- •22.1. Введение
- •22.2. Хронологические данные
- •22.3. Основная проблема хронологических баз данных
- •22.4. Интервалы
- •22.5. Интервальные типы
- •22.6. Скалярные операторы для интервалов
- •22.7. Операторы обобщения для интервалов
- •22.8. Реляционные операторы для обработки интервалов
- •22.9. Ограничения, включающие интервалы
- •22.10. Операторы обновления, включающие интервалы
- •22.11. Проектирование базы данных
- •22.12. Резюме
- •23.1. Введение
- •23.2. Обзор основных концепций
- •23.3. Исчисление высказываний
- •23.4. Исчисление предикатов
- •23.5. Базы данных с точки зрения доказательно-теоретического подхода
- •23.6. Дедуктивные субд
- •23.7. Обработка рекурсивных запросов
- •23.8. Резюме
- •Часть VI
- •24.1. Введение
- •24.2. Объекты, классы, методы и сообщения
- •24.3. Еще раз об объектах и объектных классах
- •Cdo для класса set (ref(emp))
- •24.4. Простой пример
- •1 | Course с001 , с001 0ffs , с001 ny offs |
- •24.5. Дополнительные аспекты
- •24.6. Резюме
- •25.1. Введение
- •X2 rational, y2 rational ) ... ;
- •25.2. Первая грубейшая ошибка
- •25.3. Вторая грубейшая ошибка
- •25.4. Вопросы реализации
- •25.5. Преимущества реального сближения двух технологий
- •25.6. Резюме
1 | Course с001 , с001 0ffs , с001 ny offs |
2 course"cooi
3 ;= 00s0ac detect : [ :cx | ( cx get course! ) = 'c001' ] .
4 c001 offs
5 := cqurse_c001 get_offerings .
6 c001 NY offs
7 :■ co01 offs select :
8 [ ;ox j ( ox get location ) = 'New York' ] .
9 * c001_ny_offs .
Пояснения
В строке 1 объявлены три локальные переменные: course с001, которая будет использована для хранения идентификатора объекта курса с номером 'с001'; cqoijdffs, которая будет использована для хранения идентификатора объекта "набора всех потоков" для курса с номером 'с001'; с001 ny offs, которая будет использована для хранения идентификатора набора идентификаторов для требуемых потоков (т.е. потоков, читаемых в Нью-Йорке).
В строках 2 и 3 посылается сообщение объекту (коллекции), определяемому значением переменной oosoac. Это сообщение вызывает встроенный метод DETECT данной коллекции объектов с указанием следующего аргумента.
[ :х | р(х) ]
Здесь р(х) —условное выражение, включающее переменную х, а х— переменная диапазона, изменяющаяся в пределах всех членов коллекции, к которой применяется метод detect (т.е. множества объектов course в рассматриваемом примере). В результате выполнения метода detect возвращается идентификатор первого найденного объекта этого множества, для которого выражение р(х) оказывается истинным (в рассматриваемом примере это экземпляр объекта класса COURSE для курса с номером 'С001')9, Затем идентификатор этого объекта класса COURSE присваивается переменной COURSE_C001.
Замечание. В качестве аргумента метода DETECT можно также задать некоторый аргумент "выхода" на случай, когда выражение р(х) не будет истинным ни для одного объекта в коллекции. Однако такая детализация здесь опущена.
В строках 4 и 5 переменной C001_OFFS присваивается идентификатор "множества всех потоков" для курса с номером 'СООГ.
Строки 6-8 подобны строкам 2 и 3, поскольку встроенный метод SELECT подобен методу DETECT, за исключением того, что он возвращает идентификатор коллекции идентификаторов всех объектов (вместо того чтобы указывать только на первый найденный объект), для которых выражение р(х) является истинным. В рассматриваемом примере в результате выполнения этого метода переменной C001_NY_OFFS присваивается идентификатор набора идентификаторов для тех потоков курса с номером 'CQ01', которые читаются в городе 'New York'.
В строке 9 этот идентификатор возвращается пользователю.
Следует обратить внимание на некоторые особенности приведенного примера.
9 В этом примере подразумевается, что такие методы, как GET COURCEi (аналог метода GET ЕМР#, описанного в этом разделе), уже определены.
Условное выражение р(х) в методах SELECT и DETECT может содержать (в самом сложном случае) некоторое количество простых скалярных операторов сравнения, которые соединяются с помощью операторов AND, т.е. сложность данного условия поиска ограничена.
Квадратные скобки, окружающие выражение аргумента методов SELECT и DETECT, можно заменить круглыми скобками. При использовании круглых скобок в языке OPAL будет предпринята попытка задействовать индекс (если соответствующий индекс существует), а при использовании квадратных скобок индексы задействованы не будут.
Указание, что метод DETECT возвращает идентификатор "первого найденного" объекта, для которого значением выражения р(х) будет истина, означает, что найденный объект будет первым найденным при использовании произвольной последовательности поиска, которая будет выбрана языком OPAL для просмотра коллекции (внутри набора идентификаторов не задается никакой внутренней упорядоченности). В рассматриваемом примере это замечание не имеет особого смысла, поскольку "первый" объект, для которого выражение р(х) будет истинно, фактически является единственным таким объектом.
Внимательный читатель непременно заметит выражения наподобие "метод DETECT", хотя, как отмечалось выше, методы в языке OPAL не имеют имен. Действительно, DETECT и SELECT не являются названиями методов (а потому выражения наподобие "метод DETECT" некорректны). Они, скорее всего, служат именами внешних параметров для некоторых встроенных (и анонимных) методов. Однако для краткости и простоты далее в качестве имен методов по-прежнему будут использоваться названия DETECT и SELECT (а также другие подобные им названия для других методов).
5. Кроме того, внимательный читатель заметит, что довольно часто используется выражение "метод NEW". В данном случае оно вполне корректно. В качестве исключения в языке OPAL допускается применение анонимных методов, которые не содержат каких-либо аргументов, кроме указания объекта-получателя.
Операции обновления
Объектный аналог операции вставки INSERT уже обсуждался в предыдущем подразделе, а аналоги операций обновления UPDATE и удаления DELETE рассматриваются ниже.
Обновление. Операции обновления выполняются так же, как операции извлечения, но вместо методов GET_ используются методы SET .
Удаление. Для удаления объектов используется встроенный метод REMOVE. Точнее, он используется для удаления идентификатора некоторого объекта из некоторой коллекции. Если на данный объект больше не имеется никаких ссылок, т.е. к нему вовсе не может быть осуществлен доступ, то в языке OPAL он автоматически удаляется системным процессом сборки мусора. Ниже приводится пример реализации операции "удаления сотрудника с номером 'Е001' из набора всех сотрудников".
Е001 := 0ID_0F_SET_0F_ALL_EMPS
DETECT : [ :ЕХ I (EX GETJMPt ) = 'E001' ]. 0ID_0F_SET_0F_ALL_EMPS REMOVE : E001 .
Но как в такой ситуации реализовать правило каскадного удаления DELETE CASCADE? Например, как при удалении некоторого сотрудника одновременно удалить и сведения обо всех потоках, в которых он проходит обучение? Для этого, естественно, придется создать соответствующую процедуру.
Можно прийти к заключению, что механизм реализации удаления с помощью процесса сборки мусора является всего лишь некоторой разновидностью реализации правила ограничения удаления ON DELETE RESTRICT, поскольку объект не удаляется до тех пор, пока на него существует хотя бы одна ссылка. Однако в данном случае это не совсем так. Например, объекты потоков (OFFERING) не содержат идентификаторов соответствующего объекта курса (COURSE), а потому потоки не накладывают "ограничений" на удаление объектов курсов. (В иерархиях вложения неявно подразумевается некоторая разновидность правила каскадного удаления, кроме случаев, когда пользователь выполняет следующее:
либо включает идентификатор родительского объекта в дочерний объект;
либо включает идентификатор дочернего объекта в какой-то другой объект.
В таких ситуация интерпретация "иерархии вложения" не имеет никакого смысла. В следующем разделе этот вопрос будет рассмотрен при обсуждении обратных переменных.)
В заключение заметим, что операция удаления REMOVE может быть использована для эмуляции реляционной операции DROP, например для удаления всего класса ENROLLMENT. Подробности оставляем читателю в качестве упражнения.