Россия |
Иерархические модели данных. Деревья в СУБД Cache
Выражения
В командах SET и WRITE можно вычислять сложные выражения. При этом следует помнить, что в Cache для ускорения разбора принято расшифровывать выражения слева направо, не учитывая старшинство операций. Поэтому 2 + 3 * 8 равно 40, а не 26, как учили в школе (листинг 3.5). Пользуйтесь скобками для задания порядка действий.
USER>W 2+3*8 40 USER>W "12qwerty"+4 16 USER>W "qwerty12"+4 4 USER>Пример 3.5. Чтение слева направо
Все переменные не типизированы. По сути, хранится единственный тип данных — строка переменной длины. Последовательность символов в зависимости от контекста расшифровывается слева направо, пока это возможно. Поэтому "12qwerty" в арифметическом выражении равно 12, а "qwerty12" нулю.
Выражения могут быть трех типов:
- Арифметические выражения. Содержат арифметические операторы, интерпретируют операнды как числа и возвращают числовой результат.
- Строковые выражения. Содержат строковые операторы, интерпретируют операнды как строки и возвращают результат в виде строки.
- Логические выражения. Содержат логические операторы и отношения, интерпретируют операнды как логические значения и возвращают булев результат, в котором истина передаётся как TRUE или 1, а ложь как FALSE или 0. В интерпретациях логических выражений "не 0" - это TRUE, а 0 — это FALSE. В таблице 3.1 перечислены только те операторы ObjectScript, смысл которых не вполне очевиден.
Оператор | Выполняемое действие |
\ | Целочисленное деление |
** | Степень |
# | Остаток от деления по модулю |
_ | Конкатенация (соединение строк) |
' | Логическое отрицание (NOT) |
= | Присваивание или сравнение на равенство |
‘= | Сравнение на неравенство |
[ | Содержит |
] | Следует за |
]] | Сортируется за |
&&,& | Логическое AND (&& это "короткое" AND) |
||, ! | Логическое OR (|| это "короткое" OR) |
@ | Косвенность |
? | Сравнение с шаблоном |
Допускаются комбинации '> не больше чем (меньше или равно) и '< не меньше чем.
Логические выражения
Основу логических выражений образуют операторы сравнения (=, >, <, '=, [, ], ?). Заметим, что обозначение для неравенства <> не употребляется. А вот условия <= и >= можно использовать наряду с '< и '>.
Например, R x IF x <=2 W x,"<=2"
Обратите внимание, что в качестве одиночной кавычки выбирается та, которая расположена на клавише с буквой "э".
Операторы сравнения и логические константы связываются логическими операторами AND (обозначается & или &&), OR (обозначается | или ||), NOT (обозначается ').
Предскажите и проверьте результат выполнения трёх командных строк с постусловием:
W:"1ab" "Условие истинности" W:-1 "Условие истинности" W:0 "Условие истинности"
Ответ: Первое постусловие "^^'представляет константу, интерпретируемую как логическое значение 1. Второе условие в виде константы —1 также интерпретируется как "не 0", то есть 1. И только третье соответствует ложному значению.
Краткие варианты && логического оператора "И" и || оператора "ИЛИ" отличаются от обычных & и | тем, что выполнение цепочки связанных условий прекращается, как только результат определится. Для "И" достаточно получить первый ложный результат, а для "ИЛИ" первый истинный. Условия в IF, записанные через запятую, также выполняются по краткому варианту. Поэтому для повышения скорости, необходимо первыми помещать те условия, у которых больше шансов получить ложное значение для "И" и истинное значение для "ИЛИ".
Логические и арифметические выражения могут сочетаться. Логическое выражение может использоваться для выбора арифметического значения, например, .
Для тренировки объясните работу следующих командных строк:
и
Переменные. Зарезервированные слова
Мы уже обратили внимание на то, что Cache очень лояльна к именам из второй половины ASCII таблицы. В других СУБД с ними могут возникать большие проблемы. Скажем, такие имена допускаются при создании объектов, которые затем работают с ошибками. Имена переменных должны начинаться либо с буквы, либо со знака процента (%), за ними ногут следовать буквы или цифры. Системные переменные могут начинаться с символа $.
Длина имени не ограничена, но в идентификации имён участвуют только первые 31 символов. Пользовательские имена чувствительны к регистру, а предопределённые имена команд нет.
В COS нет проверки на совпадение пользовательских имён с зарезервированными именами. Можно создать переменную с именем set, например, SET set=11, но так поступать не рекомендуется. Вы можете запутать и себя и других разработчиков.
Глобалы
Язык COS способен создавать переменные, значения которых сохраняются на диске. В противовес временным переменным, именуемым лока-лами, хранимые переменные называются глобалами. Их имена обязательно начинаются со знака "^". Как остроумно сказано в одной книге, это галочка, которая в простонародье именуется циркумплекс. Действия над глобалами осуществляются так же, как и с обычными переменными — локалами. Но WRITE без параметра их не обнаруживает.
Даже если вы ещё не создавали глобалов, то в выбранном вами пространстве имён, например USER, они уже существуют. Для проверки войдем в портал управления системой и в разделе "Управление данными (System Explorer)" выберем "Глобалы", а затем пространство USER (рисунок 3.12).
Командой S ^а=33 в терминале создаём глобал и проверяем его наличие нажав на "Просмотр глобалов"(рисунок 3.13).
Выбираем "Просмотр" или "Редактировать". Теперь можно просмотреть глобал и удалить его, а в глобале с древесной структурой удалить его весь или же отдельные узлы (рисунок 3.14).
Глобалы пространства имён XX хранятся в папке с именем XX в файле с одним и тем же именем Cache.dat. На моей машине созданный глобал^а находится в файле Cache.dat в папке C:\InterSystems\Cache\mgr\user. У вас вместо имени Cache может использоваться TryCache.
Заметим, что процессом сохранения созданных или изменённых глоба-лов пользователь управлять не может.
Ошибки
Предполагалось, что, выполняя предыдущие примеры, вы не делали ошибок. Вообще говорят, что люди делятся на умных, которые учатся на чужих ошибках и других, которые учатся на своих. Так вы этому не верьте. По крайней мере, в программировании это не так. Хорошо бы, конечно, никогда не делать ошибок. Но в реальности остаётся стараться не делать их слишком много, особо избегая непоправимых ошибок, и, самое главное, быстро исправлять сделанные ошибки. Научиться этому можно, только на своих ошибках.
Итак, вы решили определить переменную с неправильным именем 2x задав команду S 2x=1. Получаем сообщение об ошибке (листинг 3.6, первая командная строка). Ошибка (<SYNTAX>) означает синтаксически неправильно сформированную строку языка Cache ObjectScript.
Сделаем ещё одну ошибку, которая позволит выяснить, как исполняется командная строка (листинг 3.6, вторая командная строка). Ошибка <UNDEFINED> сигнализирует о том, что некоторая переменная не имеет значения. Имя переменной пишется после знака *.
USER>S 2x=1 S 2x=1 ^ <SYNTAX> USER>K S x=1,y=2,z=a,v=3 K S x=1,y=2,z=a,v=3 л ^ <UNDEFINED> *a USER>W x=1 У=2 USER>Пример 3.6. Ошибки
Вторая ошибка произошла из-за того, что переменной z мы пытались присвоить значение неопределенной переменной а. Результат выполненной позднее в третье строке команды W показывает, что командная строка читается слева направо и те её части, которые могут быть выполнены до появления ошибки (S x=1,y=2) выполняются. Появление ошибки прекращает исполнение командной строки и присваивание S v=3 не производится, хотя эта часть команды ошибки не содержит.
3.2.3 Разветвления и циклы
Разветвления в COS могут организовываться тремя способами:
- условными опциями команд (командное постусловие);
- разветвлениями языка М (команда IF, отдельная команда ELSE, системная переменная $TEST, хранящая логическое значение истинности последней проверки условия);
- классической командой ветвления (команда IF-ELSEIF-ELSE, переменная $TEST при работе с условиями не используется).
Главное различие между вариантами IF в том, что классическая команда основана на разбиении программы на блоки, а старая команда языка М этого не предполагает, хотя и допускает.
Блоком называется последовательность команд COS, заключенная в фигурные скобки. Блок может быть помещен везде, где может помещаться единственная команда. Блоки могут быть вложены.
Условные опции команд
Любая команда может быть снабжена необязательным постусловием, записываемым через двоеточие:
Команда с постусловием выполняется только если логическое выражение принимает значение ИСТИННО. Вспоминаем, что в COS принята следующая трактовка числовых значений истинности: 0 это ложно, любое другое значение — истинно. В качестве примера вводите разные значения, исполняя командную строку
R z W:z=1 !,"z=1'"
В команде передачи управления GOTO постусловия могут следовать как за командным словом GOTO, так и за любым ее аргументом:
,
где
Последний вариант это косвенность, которой мы займёмся позже.
Команда
работает, если выполнено условие
, при этом переход производится к первой метке если
, ко второй если
и к третьей в остальных случаях
. Необходимость простановки пробела перед G объясняется тем, что команду имеет смысл использовать не в командной строке, а в программе. В строке программы команды записываются со второй позиции, а сами программы рассмотрим чуть позже.
Заметим, что переход из GOTO в другую программу или другую строку той же программы выполняется без возврата в следующую за вызвавшей строку. Если требуется возврат управления, используют команду D[O], в которой за командным словом также может помещаться постусловие.
Замечание. В COS метка —это любое имя. В инструментальном средстве "Студия", которую мы рассмотрим ниже, метка записывается с первой позиции строки.
Разветвления языка М
Формат команды IF:
,
где
Каждый аргумент —это условие, возвращающее логическое значение. Системная переменная $TEST хранит логическое значение последней проверки. Набор аргументов команды IF образует условие IF (пример 3.7)
|USER>S x=1 I x=1 W "x=",x, " $TEST="_$TESTПример 3.7.
Если в IF имеется несколько аргументов, то они образуют сложное логическое условие в котором аргументы соединены логическим оператором И (AND).
Команда ELSE сделана независимой от IF. Ее формат:
Часть строки, идущая вслед за ELSE выполняется, если $TEST=0. В противном случае управление передается следующей строке. Обратите внимание, что после ELSE записывается два пробела (пример 3.8)
USER>S x=1 I x=2 W "x=", x USER>W "$TEST="_$TEST USER>E W xПример 3.8.
Существует еще безаргументный IF, записываемый в виде:
Понятно, что он использует последнее значение $TEST, установленное другими командами. При сложных проверках, осуществляемых в ветвящихся и циклических программах, использование такого синтаксиса может сильно затруднить отладку.
Заметим, что постусловия, в отличие от команды IF, не используют переменную $TEST и потому они не могут повлиять на команду ELSE.