Cредства разработки Informix-L
Кодовое представление на стороне клиента содержит в себе:
логику управления экраном на Informix-4GL и пользовательский интерфейс;
предложения SQL, которые направляются серверу Informix для обработки.
При написании своего приложения на языке Informix-4GL перед пользователем возникает задача выбора - какую версию из языковых средств Informix-4GL ему рационально использовать.
Система программирования Informix-4GL реализована в двух версиях:
Informix-4GL Compiler Version - компилятор, преобразующий 4GL-программу с языка Informix-4GL в программу на языке Informix-ESQL/C, которая затем компилируется и линкуется с другими объектными модулями в выполняемый командный файл;
Informix-4GL RDS - система быстрой разработки (Rapid Development System), содержащая в своем составе процедуры компиляции и запуска программ на языке Informix-4GL и создающей приложение на p-коде, полностью совместимое с приложением, подготовленным компилятором Informix-4GL.
Оба средства используют один и тот же способ кодирования и одни и те же предложения Informix-4GL, но отличаются схемой реализации фаз компиляции и исполнения.
В случае RDS производится компиляция исходного кода, представленного на Informix-4GL (файл source.4gl) в псевдокод, т.е. р-код (файл source.4go). Одна из причин названия языкового средства как Rapid Development System заключается в том, что время компиляции по такой технологической цепочке будет достаточно малым. Компоновка программы из отдельных объектных модулей (файл prog.4gi) производится их механическим объединением.
Время на компиляцию для языкового средства Informix-4GL Compiler Version значительно больше. Сначала программное представление на Informix-4GL (файл source.4gl) транслируется в код на ESQL/C. Полученный файл (файл source.ec) преобразуется в код на языке С, с получением файла source.c. Далее source.c преобразуется в объектный код (файл source.o). Наконец, производится преобразование объектного кода в двоичный код (файл prog.exe), пригодный для машинного исполнения.
В представленном рассмотрении нет никаких доводов, чтобы не использовать Informix-4GL RDS. Но прежде чем сделать окончательный вывод, следует обратить внимание, как будет протекать фаза исполнения по этим двум вариантам Informix-4GL.
Если результатом работы Informix-4GL С Compiler Version является готовая программа (либо полученная в результате объединения объектных модулей), которая может быть непосредственно запущена, то Informix-4GL RDS генерирует псевдокод, который не может быть непосредственно использован компьютером. Поэтому исполнитель такого псевдокода (программная компонента fglgo) выбирает предложения, написанные на Informix-4GL и транслирует их в представление, которое может быть выполнено на машине. Поэтому при использовании Informix-4GL RDS может потребоваться достаточно много времени на исполнение.
Версия Informix-4GL | Запуск на выполнение |
Informix-4GL С Compiler Version | $ prog.exe |
Informix-4GL RDS | fglgo prog.4gi |
Первым важным преимуществом RDS является возможность использования графических представлений в ваших RDS приложениях с помощью средств Informix-4GL/GX (программная компонента fglgx). При этом не требуется перепрограммирования, рекомпиляции или повторного линкования. Informix-4GL/GX работает с GX дисплеем, с использованием пользовательского интерфейса, где применимы те же базовые конструкции, что и в символьно-ориентированной версии Rapid Development System. При запуске в режиме GX обеспечиваются:
доступ с помощью мыши;
трехмерная обработка полутонов;
замена текстовых полей и их разделителей визуально различимыми полями формы.
Вторым существенным преимуществом Informix-4GL RDS является наличие в ней интерактивного отладчика Informix-4GL Interactive Debugger, который весьма удобен для трассировки переменных в вашей исходной программе и построчного исполнения программы.
Таким образом можно рекомендовать выполнение разработки вашего приложения с использованием Informix-4GL RDS, а затем откомпилировать полученный продукт, используя Informix-4GL С Compiler Version.
Динамический SQL
В ряде приложений возникает необходимость в динамическом формировании SQL-операторов по ходу выполнения программы. Этого могут потребовать:
интерактивные программы, в которых пользователь вводит данные и тем самым формирует запрос с терминала;
программы, предназначенные для работы с различными базами данных, структура которых может меняться.
С помощью динамического SQL программа-клиент выполняет программное формирование оператора SQL для его последующего исполнения, делая это в три этапа:
программа собирает текст оператора SQL в виде символьной строки, хранящейся в программной переменной; в общем случае это может быть не один, а несколько операторов SQL, разделенных точкой с запятой;
программа выполняет оператор Prepare, который обращается к серверу баз данных на предмет изучения текста оператора и подготовки его к выполнению;
программа использует оператор Execute для выполнения подготовленного оператора.
Подготовка операторов
Динамический оператор SQL по форме напоминает любой другой SQL-оператор, записанный в программе, с тем ограничением, что он не может содержать имена главных переменных. Поэтому
в динамический оператор Select нельзя включать спецификатор Into, в котором используются главные переменные;
в любом месте, где главная переменная могла бы появиться в выражении SQL-оператора, ей соответствует знак вопроса.
При формировании оператора Prepare можно воспользоваться как символьной строкой (либо функцией, возвращающей символьное значение), так и ранее определенной символьной переменной. Результатом выполнения оператора Prepare является структура данных, имеющая имя и отображающая строку символов с текстом оператора SQL.
В общем случае оператор Prepare не ограничивает символьную строку одним SQL-оператором и может содержать группу SQL-операторов, разделенных точкой с запятой.
Значения главных переменных, используемые при формировании SQL-оператора, могут быть получены из пользовательского ввода и присоединены к текстовой строке на этапе формирования SQL-оператора.
В этом случае отпадает необходимость использования знака "?".
Указатели позиции "?" не могут быть использованы вместо идентификаторов SQL таких, как имя базы данных, имя таблицы или столбца: эти идентификаторы должны указываться в тексте оператора при его подготовке. Если эти идентификаторы не известны во время написания программы, они могут быть получены из пользовательского ввода, аналогично предыдущему примеру.
Замечаниe. Запрещенными для динамического формирования являются операторы, непосредственно связанные с динамическим SQL (Prepare, Execute), операторы управления курсором (Declare, Open, Fetch, ...), а также операторы работы на уровне базы данных (Create database, Database, ...).
Выполнение подготовленного SQL-оператора
Подготовленный по оператору Prepare динамический оператор (группу операторов) можно многократно выполнять. С помощью оператора Execute выполняются операторы, отличные от операторов Select, а также операторы Select, которые возвращают в качестве результата одну строку. Если оператор Select возвращает более одной строки, динамический оператор Select выполняется не с помощью оператора Execute, а подключается к курсору и в дальнейшем используется обычным образом с помощью курсорных средств. В обоих случаях при выполнении динамического оператора с помощью спецификатора Using ему передаются главные переменные, участвующие в выражениях и принимающие возвращаемые значения и, по сути, играющие роль фактических параметров .
Последний пример иллюстрирует случай использования курсора для выполнения динамически подготовленного оператора. Последовательность выполнения действий в примере:
Символьная строка, задающая оператор Select, помещается в программную переменную. Она содержит два заполнителя, отмеченных знаком вопроса.
Оператор PREPARE преобразует символьную строку в структуру данных с именем q_orders, которая может быть выполнена.
Объявляется курсор с именем cu_orders и связывается с именем подготовленного оператора.
Вводятся необходимые параметры для SQL-оператора.
При открытии курсора выполняется подготовленный оператор. Спецификатор Using в операторе Open указывает имена двух главных переменных, содержимое которых заменяет знаки вопроса, указанные в исходном операторе.
Первая строка данных выбирается с помощью открытого курсора. Спецификатор Into оператора Fetch специфицирует главные переменные, которые должны принимать значения столбцов строки, выбранной по курсору.
Оператор Free служит для освобождения памяти. Оператор Free получает либо имя оператора, либо имя курсора, объявленного для оператора с этим именем, и освовождает память, занятую подготовленным оператором.
Для простых операторов, не требующих курсора или главных переменных, можно объединить действия операторов Prepare, Execute, Free в одной операции. Оператор Execute Immediate получает строку символов, подготавливает ее, выполняет и освобождает память.
Файл спецификации экранной формы
Файлы спецификации формы состоят из трех обязательных секций (Database, Screen, Attributes) и двух необязательных (Tables, Instructions), расположенных в указанном ниже порядке.
Секция Database
Секция Database идентифицирует базу данных, характеристики столбцов таблиц которой будут использоваться для определения полей экранной формы на этапе ее компиляции утилитой Form4gl, либо указывает (FORMONLY), что для определения полей экранной формы не требуется какая-либо база данных.
Database {имя_БД | FORMONLY} [WITHOUT NULL INPUT],
где WITHOUT NULL INPUT - условие, запрещающее ввод NULL-значений.
Cекция Screen
Секция Screen задает точное расположение формы на экране.
Screen [SIZE lines [BY cols]]
{
[text] [field-tag] [graphics-char]
[text] [field-tag] [graphics-char]
. . .
}
[END]
По умолчанию число строк и символов равно соответственно 24 и 80.
Описание формата экрана состоит из массива полей экрана и текстовой информации, такой, как заголовки, поясняющие записи и т.д.
Правила описания полей экранной формы:
поля задаются квадратными скобками, определяющими местоположение и ширину поля, и тэгами field-tag (ярлыками, метками, признаками) полей, идентифицирующими поле в секциях Attributes и Instructions;
имена тэгов записываются по правилам записи идентификаторов;
имена тэгов не есть то же самое, что имена полей; секция атрибутов связывает каждый тэг с именем поля;
один и тот же тэг может быть использован более чем в одной позиции секции Screen;
ширина полей для числовых величин должна быть достаточной для размещения максимального из чисел;
в случае данных типа CHAR символьные строки при необходимости могут усекаться.
Дополнительно отметим графические символы для рисования рамок
\gp------------------q\g
\g| |\g
\gb------------------d\g
Ниже представлено описание секции Screen приведенной выше экранной формы Example1.per.
Секция Tables
Секция Tables специфицирует таблицы, характеристики столбцов которой будут использоваться для определения полей экранной формы на этапе ее компиляции утилитой Form4gl.
Tables
table | table_alias=[database [@server] :][owner.]]таблица
table | table_alias=[database [@server] :][owner.]]таблица
. . . . . . . . . . .
[End]
Ниже приведено возможное описание секции Tables.
Секция Attributes
Секция Attributes описывает поведение, внешний вид, допустимые входные значения, значения по умолчанию каждого поля в секции Screen и связывает каждое поле с именем поля. Каждое поле в секции Screen должно быть описано в секции Attributes. Порядок, в котором описаны поля секции Attributes, задает порядок по умолчанию перемещения курсора на экране.
Attributes
field-tag=field-description;
field-tag=field-description;
. . .
[End]
Двумя важнейшими атрибутами каждого поля являются имя поля и тип поля. Имя поля - это имя, используемое 4GL-программой для отображения в поле экранной формы данных при вводе или выводе. Тип поля может быть задан явно, либо неявно и обусловлен видом полей экранной формы:
поля формы, связанные со столбцами таблиц базы данных;
поля формы, не связанные со столбцами таблиц базы данных и носящие название Formonly.
Связь экранных полей со столбцами таблиц базы данных устанавливается во время компиляции файла экранной формы и служит для извлечения атрибутов столбцов (тип данных, длина и т.д.). Указанное имя столбца name_column становится именем поля и получает все характеристики столбца. В дальнейшем связь разрывается и имя поля служит связующим звеном между полями экрана и столбцами таблицы базы данных.
Формат описания полей, связанных со столбцами:
field-description =[table.]name_column[,attribute-list];
Имя или псевдоним таблицы обязателен лишь в том случае, когда одно и то же имя столбца упоминается более чем в одной таблице в экранной форме. С помощью вырезок в поле могут быть отображены части столбцов типа Char.
Второй тип связи используется для описания полей, не связанных со столбцами таблиц базы данных. Формат описания данного типа связи:
field-description =Formonly.field-name
[Type [data-type | LIKE table.column]]
[NOT NULL][,attribute-list];
Назначение записанных выше параметров:
Formonly - ключевое слово, информирующее, что поле field-tag не связано со столбцом таблицы базы данных и 4GL-программе доступно под именем field-name;
Type - тип данных в соответствии с типами данных Informix с длиной, определенной шириной отображения (по умолчанию предполагается CHAR);
NOT NULL - ключевое слово, информирующее, что поле обязательно должно иметь введенное значение.
Ниже приведен перечень атрибутов attribute-list, служащих для уточнения свойств полей:
1. AUTONEXT - автоматическое перемещение курсора в следующее поле после заполнения текущего при выполнении операции ввода
field-tag = table_column, AUTONEXT, . . .
2. COLOR - вывод текста поля на экран в цвете
field-tag = table_column,
COLOR=[color][ligth][WHERE условие 2 на field-tag], . . .
Список значени цвета и интенсивности изображения приведен выше.
3. COMMENTS - определение сообщения-подсказки
field-tag = table_column, COMMENTS="сообщение", . . .
4. DEFAULT - задание значения по умолчанию
field-tag = table_column, DEFAULT=значение.
5. DOWNSHIFT - замена прописных букв на строчные
field-tag = table_column, DOWNSHIFT, . . .
6. FORMAT - управление форматом вывода на экран для столбцов типа DECIMAL, SMALLFLOAT, FLOAT, DATE
field-tag = table_column, FORMAT="строка_формата", . . .
Строка_формата может содержать символы:
# - для представления цифры; mm, dd, yy - месяц, день, год для данных типа даты в различной форме представления и т.д.
7. INCLUDE - задание полю допустимых значений
field-tag = table_column, INCLUDE=(sense_list) , . . .
где sense_list - список, определяемый отдельными значениями (значение1, значение2, . . .), диапазоном значений (значение1 ТО значение2) или их комбинацией.
8. NOENTRY - предотвращение ввода данных во время операции добавления
field-tag = table_column, NOENTRY, . . .
9. NOUPDATE - предотвращение ввода данных во время операции обновления
field-tag = table_column, NOUPDATE, . . .
10. PICTURE - указание шаблона для вводимых символьных данных
field-tag = table_column, PICTURE="picture-string" , . . .
где picture- string - комбинация из трех символов: А - любая буква, # - любая цифра, X - любой символ.
11. REQUIRED - требование принудительного ввода данных в указанные поля во время операции добавления.
field-tag = table_column, REQUIRED, . . .
12. REVERSE - вывод на экран в реверсном изображении
field-tag = table_column, REVERSE, . . .
13. UPSHIFT - преобразование строчных букв в прописные.
field-tag = table_column, UPSHIFT, . . .
14. VERIFY - требование от пользователя ввода полей дважды, чтобы снизить вероятность ошибки при вводе.
field-tag = table_column, VERIFY, . . .
15. WORDWRAP - необходимость расположения длинной символьной строки в нескольких полях, имеющих один и тот же тэг
field-tag = table_column, WORDWRAP, . . .
Ниже представлено описание секции Screen приведенной выше экранной формы Example1.per.
Секция Instructions
Секция Instruction используется для
для задания разграничителей полей;
определения экранных записей и массивов.
Секция начинается с ключевого слова Instructions и заканчивается необязательным ключевым словом END.
По умолчанию в качестве разграничителей полей выступают символы "[" и "]". Для изменения их в инструкции DELIMITERS данной секции в кавычках указываются два символа, определенных в качестве разграничителя для данной экранной формы.
Экранные записи и массивы служат для объединения экранных полей в группы.
Инструментарий разработчика L-программы
Система программирования Informix-4GL включает:
средства компиляции с языка Informix-4GL;
генератор и компилятор экранных форм;
средства подготовки help-файла.
Версия компилятора Informix-4GL представлена программной компонентой c4gl. Ниже приведен упрощенный синтаксис команды c4gl.
Версия Informix-4GL RDS представлена программными компонентами fglpc, fglgo, из которых первая используется на этапе подготовки приложения, а вторая - при его запуске. Ниже приведен упрощенный синтаксис команд fglpc, fglgo.
Компилятор экранных форм Informix-4GL представлен программной компонентой form4gl, преобразующей текст экранной формы (файл form.per) в файл form.frm, который может вызываться из 4GL-программы.
Приведенные в диаграммах обозначения имеют смысл:
source.4gl - имя исходной программы на языке Informix-4GL;
esqlc.ec, source.c, obj.o, yourlib - соответственно исходные модули на языке ESQL/C, Си, объектные модули и библиотеки, дополнительно подключаемые при использовании компилятора c4gl;
-о outfile - имя создаваемого выполняемого файла при использовании компилятора c4gl (по умолчанию a.out); при использовании системы быстрой разработки fglpc имя создаваемой на выходе программы на р-коде source.4go;
- e - выполнить только препроцессорную обработку;
-V - указание получить информацию о версии программы;
argument - аргументы при запуске программы на выполнение;
filename - имя запускаемого файла в системе быстрой разработки (полученные программой fglpc файлы filename.4go, либо полученные конкатенацией файлов filename.4go файлы filename.4gi);
form.per - имя файла с экранной формой;
-d - указание сгенирировать экранную форм по умолчанию;
- database-name, table-name - имя базы данных и имена таблиц при генерации экранной формы по умолчанию.
Для подготовки help-файла используется утилита mkmessage первым параметром указывается имя текстового файла, вторым - имя формируемого утилитой mkmessage откомпилированного файла.
Использование экранных форм в Informix-L
Для использования экранной формы в Informix-4GL необходимо:
подготовить текстовый файл со спецификацией экранной формы (расширение .per) и откомпилировать его утилитой form4gl в файл с расширением .frm; единственным параметром утилиты является имя текстового файла с экранной формой;
снабдить 4GL-программу операторами, обеспечивающими взаимодействие с экранной формой.
Ниже приведен пример отображения данных через экранную форму, на которую в дальнейшем будем ссылаться как Example.per.
Использование курсоров в операциях модификации данных
Для повышения эффективности выполнении операций Delete, Update и Insert можно использовать специальные формы курсоров.
Использование курсоров для удаления текущей строки
Для удаления строки, которая была выбрана по курсору последней, необходимо использовать оператор Delete совместно с курсором. Для этого следует включить конструкцию FOR UPDATE в оператор Declare для последовательного курсора и конструкцию Where Current of в последующий оператор Delete.
Ниже приведен пример программы, удаляющей строки с дубликатами номеров заказов.
Использование курсоров для корректировки текущей строки
Для корректировки строки, которая была выбрана по курсору последней, необходимо использовать оператор Update совместно с курсором. Для этого следует включить конструкцию FOR UPDATE в оператор Declare для последовательного курсора и конструкцию Where Current of в последующий оператор Update.
Перечисление в конструкции FOR UPDATE оператора Declare имен столбцов указывает на недопустимость корректировки столбцов, имена которых отличны от названных. Любая попытка корректировки необозначенных столбцов вызовет ошибку.
В нижеприведенном фрагменте программы из столбца Datcol таблицы Target удаляются ошибочно занесенные NULL-значения, а в столбец Serial заносятся неповторяющиеся значения целого типа.
Использование курсоров для вставки
Курсор для вставки оператора Insert используется совместно с операторами PUT, FLUSH, которые позволяют выполнить более эффективный ввод данных в базу данных, благодаря буферизации данных в памяти.
PUT | Устанавливает буфер ввода для курсора оператора Insert. PUT сохраняет строку в буфере оператора Insert для последующего ввода в базу данных. Когда буфер заполнен целиком, он автоматически записывается в требуемую таблицу как блок. |
FLUSH | Принудительно переносит строки из буфера в таблицу базы данных. |
Приведенный ниже фрагмент программы заполняет базу данных с использованием аппарата курсора. Используемая в тексте функция next_cust возвращает либо информацию о новом клиенте, либо Null-значение, сигнализирующее об окончании ввода. Если эта функция возвращает значение, отличное от NULL-значения, оператор PUT посылает полученные данные в буфер строк. Когда буфер заполняется, строки, которые он содержит, автоматически пересылаются на сервер. Цикл нормально завершается, когда next_cust перестает возвращать данные.
Замечание. Использование курсорных средств и операторов PUT, FLUSH взамен оператора INPUT приводит к более быстрому исполнению программы.
Экранные записи и экранные массивы
Экранная запись представляет собой объединение полей экранной формы в единое целое в секции INSTRUCTIONS
SCREEN RECORD record-name
({table_name.*|
table_name.column THRU table_name.column |
table_name.column} [, . . . ])
Элементы экранной записи указываются либо их перечислением, либо заданием диапазона имен полей в порядке их следования в секции ATTRIBUTES (THRU), либо это может быть полный список. При этом table_name может быть FORMONLY, либо именем таблицы базы данных. В 4GL-программе экранная запись доступна под именем record-name.
В нижеприведенном примере часть полей, соответствующих столбцам таблицы Customer (заказчик), ассоциируются с экранной записью. Такая экранная запись позволяет упростить операторы Informix-4GL для корректировки реквизитов заказчика. Все поля, соответствующие столбцам таблицы Customer из указанного диапазона, составляют экранную запись Adress.
Группа из n экранных записей в свою очередь может быть объединена в экранный массив.
Описание экранного массива выполняется в секции INSTRUCTIONS конструкцией
SCREEN RECORD record-name[n]
({table_name.*|
table_name.column THRU table_name.column |
table_name.column} [, . . . ])
Для приведенной выше экранной формы Example1.per описание используемого в ней экранного массива из пяти записей может быть выполнено в виде
Следующая иллюстрация показывает как связаны между собой описания экранного массива в секциях Screen, Attribute и Instructions.
Экранный массив является средством организации так называемого скроллирующего массива, когда на экране при нажатии курсорных клавиш отображается скроллирующий список строк, число которых превышает физический размер области экрана, предназначенной для ввода этих строк.
Обработка многострочных запросов с использованием аппарата курсоров
Обработка многострочного запроса осуществляется в два этапа. Сначала программа дает старт запросу, после которого не возвращаются никакие данные. Затем программа запрашивает строки данных по одной на каждое требование. Эти операции выполняются с помощью специального объекта данных, называемого курсором. Курсор является структурой данных, представляющей текущее состояние запроса. Основная последовательность программных операций с курсором выглядит следующим образом:
Программа объявляет курсор и ассоциированный с ним оператор Select. Это приводит лишь к выделению памяти для хранения курсора.
Программа открывает этот курсор, что приводит к началу выполнения ассоциированного оператора Select.
Программа считывает очередную строку данных в главные переменные и обрабатывает их.
Программа закрывает курсор после прочтения последней строки.
Эти операции выполняются с помощью операторов SQL Declare, Open, Fetch, Close, Foreach.
Множество строк, возвращаемое предложением Select, называется активным множеством. В любой момент времени 4GL-программа может работать только с одной строкой - это текущая строка, на которую указывает курсор. Курсор может находиться в одном из двух состояний: открытом и закрытом. Когда курсор открыт, он связан с открытым множеством и может указывать либо на текущую строку, либо между строк, либо перед первой строкой, либо после последней строки. Если курсор находится в закрытом состоянии, он больше не связан с активным множеством, хотя и остается связанным с оператором Select.
Объявление курсора
В процессе использования курсор может задаваться в двух режимах: последовательном и скроллирующим. Последовательный курсор позволяет просматривать активное множество только в последовательном порядке, а также может использоваться при модификации и удалении строк из активного множества. Скроллирующий курсор позволяет просматривать строки из активного множества в произвольном порядке.
Оператор Declare объявляет курсор, задавая его имя, специфицируя его использование и связывая с курсором оператор Select.
Оператор Declare не является активным оператором, он только устанавливает свойства курсора и выделяет для него память. Область действия курсора - от точки его объявления до конца файла. Примеры объявления курсора приведены ниже.
Открытие и закрытие курсора
Когда программа готова к использованию курсора, она его открывает (активизирует) оператором Open. По оператору Open ассоциированный с курсором оператор Select передается серверу базы данных, который начинает поиск соответствующих строк. Сервер обрабатывает этот запрос до момента нахождения или конструирования первой строки результата. Он реально не возвращает эту строку данных, но устанавливает код возврата в переменную STATUS (sqlca.sqlcode). Если переменная STATUS равен нулю, оператор синтаксически правилен и курсор готов к использованию. Оператор Close, напротив, переводит курсор в закрытое состояние и освобождает активное множество.
Курсорная выборка строк
Оператор Fetch служит для выборки строки результата: он именует курсор, переводит курсор к определенной строке активного множества и выбирает значения из этой строки. Оператор Fetch может также задавать имена главных переменных для приема данных в спецификаторе Into, который нужно включать либо в оператор Select, либо в оператор Fetch, но не в оба сразу. Вторая форма имеет то преимущество, что разные строки могут быть считаны в разные переменные. Если оператор Fetch перемещает курсор перед первой строкой или после последней строки, в переменную STATUS (sqlca.sqlcode) устанавливается код возврата NOTFOUND (100).
Последовательность выбора строк из активного множества определяется типом курсора. Последовательный курсор, будучи открыт один раз, читает строки из активного множества строго последовательно. Единственным значением спецификатора перемещения курсора, используемым по умолчанию, является next.
При необходимости выполнить группу действий для каждой строки результата (режим Row-by-Row) можно воспользоваться оператором FOREACH ... END FOREACH.
При его использовании отпадает необходимость в ручном открытии и закрытии курсора.
Скроллирующий курсор позволяет выбирать строки из активного множества в произвольном порядке, основываясь на значении спецификатора перемещения курсора.
Next | Выбор следующей строки активного множества. |
Previous | Выбор предыдущей строки активного множества. |
First | Выбор первой строки активного множества. |
Last | Выбор последней строки активного множества. |
Current | Выбор текущей строки активного множества (той, что была прочитана ранее). |
Relative | Выбор n-й строки относительно текущей позиции курсора из активного множества. |
Absolute | Выбор n-й строки активного множества (нумерация с 1). |
Приведенный ниже пример иллюстрирует использование скроллирующего курсора при выборе каждой второй строки из некоторой группы.
Ниже приведен фрагмент программы для поиска и отображения строк таблицы.
Общие принципы организации экранного взаимодействия
В любой момент времени на экране терминала существует текущее окно, через которое и выполняется весь ввод/вывод программы. С окном связаны используемые операторами языка при вводе/выводе атрибуты и номера строк окна. При открытии нового окна оно становится текущим и последующий ввод/вывод будет направляться уже в него.
Ниже приведен набор операторов организации экранного взаимодействия. Самые простейшие из них (Prompt, Display) уже использовались в текстах примеров предыдущих разделов.
Display | Вывод данных в следующую строку. |
Display . . . at | Вывод данных в указанные позиции экрана. |
Display Form | Отображение предварительно подготовленной экранной формы. |
Display . . . to (Display by name) | Вывод данных в поля экранной формы. |
Prompt | Вывод списка значений и ввод пользователем переменной, указанной конструкцией FOR. |
Input | Ввод данных в поля или экранные массивы экранной формы. |
Construct | Ввод пользователем критерия поиска в поля экранной формы. |
Message | Вывод короткого сообщения-предупреждения. |
Error | Вывод короткого сообщения об ошибке. |
Menu | Отображение и работа c горизонтальным меню. |
Для большинства операторов экранного взаимодействия определены значения по умолчанию для строк относительно первой и последней строки окна или экрана.
Название строки | Назначение | Строка по умолчанию | Привязка |
Prompt | Ввод-вывод по оператору PROMPT | FIRST | 4GL-window |
Menu | Кольцевое меню занимающее две строки | FIRST | 4GL-window |
Message | Вывод по оператору Message | FIRST+1 | 4GL-window |
Form | Начальная строка экранной формы | FIRST+2 | 4GL-window |
Comment | Комментарий к текущему полю формы | LAST LAST-1 | 4GL-window 4GL-screen |
Error | Вывод по оператору Error | LAST | 4GL-screen |
Display (без фразы at) | Вывод выражений, заданных в операторе Display | следующая | 4GL-window |
Ниже приведен пример использования простейших средств экранного взаимодействия.
Создание и открытие окна выполняется оператором OPEN WINDOW.
Window- name является глобальным для программы, в которой оно открывается. Когда открывается окно, для него используются параметры, специфицированные по умолчанию, либо заданные оператором OPTIONS для строк MESSAGE, PROMPT, FORM, COMMENT, ERROR. Эти значения могут быть скорректированы предложением ATTRIBUTE в операторе OPEN WINDOW.
Значение атрибута | Значение по умолчанию |
BORDER | нет границы |
атрибут цвета | цвет изображения на экране |
REVERSE | нет обратного изображения |
PROMPT LINE | FIRST (1) |
MESSAGE LINE | FIRST+1 (2) |
FORM LINE | FIRST+2 (3) |
COMMENT LINE | LAST-1 (для экрана) |
LAST (для всех окон, кроме экрана) |
WHILE | RED | BLUE | INVISIBLE |
YELLOW | CYAN | BLACK | BOLD |
MAGENTA | GREEN | DIM | NORMAL |
Дополнительные операторы CURRENT WINDOW, CLEAR WINDOW, CLOSE WINDOW служат соответственно для определения текущего окна, очистки и закрытия окна.
Общие принципы работы с SQL в Informix-L
В Informix-4GL операторы SQL встраиваются в исходную программу так, как если они были бы выполняемыми операторами ее основного языка.
Выполнение оператора SQL фактически является вызовом сервера базы данных. Информация должна передаваться от программы-клиента программе-серверу и возвращаться обратно. Часть этих взаимодействий осуществляется через так называемые главные переменные, посредством которых передаются входные данные для SQL-описаний и возвращаются результаты запроса. Ни при объявлении, ни при использовании внутри SQL-описаний главные переменные в языке Informix-4GL никак не выделяются и не отличаются от обычных переменных языка Informix-4GL. SQL-описания в программе на языке Informix-4GL так же, как и главные переменные, никак не выделяются.
Для обработки ошибок, связанных с выполнением SQL-запросов в программе на языке Informix-4GL, доступна структура SQLCA, описанная в прил. А [5]. Доступ к отдельным полям структуры выполняется обычным образом (sqlca.sqlcode, sqlca.sqlerrd[3] и т.д.). Переменная sqlca.sqlcode доступна также в 4GL-программе под именем STATUS, если проверка значения STATUS выполняется непосредственно после SQL-запроса. При этом STATUS устанавливается в 0, если оператор выполнен правильно, в отрицательное значение в случае ошибки и равен NOTFOUND (100), если операторы Select или Fetch не нашли никаких строк данных. Если переменная STATUS проверяется после 4GL-оператора, она содержит код завершения последнего оператора языка Informix-4GL.
К простейшим формам SQL-запросов относятся операторы SELECT, возвращающие единственную строку, а также SQL-операторы, выполняющие простейшие действия по модификации базы данных без использования аппарата курсора.
Единственным отличием приведенных выше SQL-запросов от интерактивных SQL-операторов [7,8] является наличие спецификатора Into, задающего главные переменные, которые используются как получатели данных и в условии Where. Если записанный выше оператор Select производит более одной строки данных, то сервер базы данных возвратит код ошибки.
В SQL- запросе не требуется, чтобы главная переменная, в которую помещается значение, имела бы в точности такой же тип данных, что и в таблице. Сервер делает все возможное для преобразования данных из столбцов в форму, используемую переменными-получателями этих данных.
Как уже отмечалось ранее, Informix-4GL поддерживает NULL-значения переменных. Их использование показано на примере.
Замечание. В программе на Informix-4gl оператор Database может преследовать две цели; одна - процедурная, другая - непроцедурная. Этот оператор делает базу данных текущей (процедурная цель) и говорит компилятору, где найти информацию о составе столбцов таблиц для использования при исполнении конструкции LIKE и нотации <имя таблицы>.* (непроцедурная цель). Если указанных конструкций в программе нет, то оператор Database может появиться с процедурной целью в любом месте программы, с непроцедурной целью оператор Database должен появиться за пределами программы и предшествовать блоку GLOBALS с тем, чтобы компилятор при обработке конструкций LIKE и <имя таблицы>.* имел информацию о составе таблиц базы данных на этапе трансляции.
Операторы языка Informix-L для работы с экранными формами
Операторы языка Informix-4GL обеспечивают следующий набор действий с экранной формой:
открытие экранной формы (OPEN FORM);
отображение экранной формы (DISPLAY FORM);
отображение данных в экранную форму (DISPLAY);
отображение программного массива в экранном массиве с обеспечением скроллирования массива (DISPLAY ARRAY);
ввод данных через экранную форму (INPUT);
ввод данных через экранный массив (INPUT ARRAY);
закрытие экранной формы (CLOSE FORM).
Оператор OPEN FORM связывает идентификатор Informix-4GL form-name c откомпилированным файлом экранной формы и должен предшествовать всем операциям с экранной формой.
Оператор DISPLAY FORM отображает экранную форму, начиная с третьей строки (если это не изменено предложением ATTRIBUTE оператора OPEN WINDOW) экрана терминала или окна, возможно, со своими атрибутами, определяющими цветовую гамму.
Отметим, что указание опции WITH FORM в операторе OPEN WINDOW равносильно паре операторов OPEN FORM и DISPLAY FORM.
Оператор DISPLAY в случае работы с формами позволяет:
отображать список программных переменных либо элементов программной записи, содержащих какую-либо информацию (в том числе и из таблиц базы данных) в указанные поля экранной формы с использованием имен полей экранных формы (DISPLAY . . . TO . . .);
отображать элементы программной записи (предварительно созданные по DEFINE variable-record RECORD . . . ) в поля экранной записи (DISPLAY variable-record.* TO screen-record.*);
отображать список программных переменных в поля экранной формы с использованием конструкции DISPLAY BY NAME . . . при условии совпадения имен программных переменных с именами полей экранной формы;
задавать при отображении данных собственные атрибуты, определяющие цветовую гамму.
Приведенный пример демонстрирует отображение значений программных переменных в поля экранной формы Example1.per в случае неидентичности имен переменных и имен полей, указанных в секции Attributes.
В следующем примере имена отображаемых значений и используемые поля экранной формы совпадают, что позволяет применять конструкцию BY NAME и не различать имена программных переменных и экранных полей.
Поскольку экранные записи являются лишь средством группирования полей экранной формы, работа с ними выполняется теми же операторами языка Informix-4GL, что и ввод/вывод в поля/из полей экранной формы: по каждому оператору DISPLAY элементы записи, определенной в 4GL-программе и имеющие те же характеристики, что и элементы экранной записи, отображаются в поля экранной формы, ассоциированные с этой экранной записью; по оператору INPUT выполняется обратная операция, по которой вводимые данные из полей экранной формы, составляющие экранную запись, переносятся в элементы программной записи. В обоих случая в 4GL-операторах указываются лишь имена программных и экранных записей.
Если в секции Instructions экранной формы Example1.per из полей экранной формы описана экранная запись
то для отображения программных переменных или элементов программной записи также используется конструкция TO оператора DISPLAY.
P ALIGN="JUSTIFY">Оператор INPUT позволяет:
вводить список указанных программных переменных через поля экранной формы, используя имена полей экранной формы (INPUT. . . FROM . . .);
вводить список программных переменных через поля экранной формы с использованием конструкции INPUT BY NAME . . . при условии совпадения имен программных переменных с именами экранных полей экранной формы;
вводить элементы программной записи (предварительно созданные по DEFINE variable-record RECORD . . . ) через поля экранной записи (INPUT variable-record.* FROM screen-record.*);
определять использование/не использование значений по умолчанию для полей формы (WITHOUT DEFAULTS);
задавать действия по обработке до/после ввода данных в поле (BEFORE FIELD/AFTER FIELD, а также контролировать вводимые значения;
определять порядок ввода данных в поля экранной формы (NEXT FIELD); при отсутствии NEXT FIELD порядок обхода полей экранной формы определяется последовательностью полей в списке INPUT;
определять действия, которые необходимо выполнить при нажатии указанных функциональных или управляющих клавиш (ON KEY);
использовать help-сообщения из help-файла (HELP);
проверять значение текущего поля с использованием функции infield(field), возвращающей значение true/false;
при необходимости прерывать ввод (EXIT INPUT).
Ввод данных по оператору INPUT завершается нажатием клавиши ESC, либо управляющей клавиши, определенной параметром ACCEPT KEY в операторе OPTIONS, либо нажатием клавиши RETURN после ввода последнего поля экранной формы при условии действия опции INPUT NO WRAP в операторе OPTIONS. В случае опции INPUT WRAP в операторе OPTIONS нажатие клавиши RETURN после ввода последнего поля экранной формы приводит к циклическому перемещению на первое поле экранной формы.
Следующий пример демонстрирует ввод значений элементов программной записи из полей экранной записи и использование конструкции WITHOUT DEFAULTS.
Ниже приведены примеры использования различных конструкций оператора INPUT.
Отметим, что ввод с использованием экранной формы напрямую не связан с занесением информации в таблицы базы данных.
Оператор CLOSE FORM разрывает связь с экранной формой.
Схема организации скроллирующего массива следующая:
в секции INSTRUCTIONS экранной формы определяется экранный массив;
в 4GL-программе оператором DEFINE определяется массив достаточной размерности, элементами которого являются записи, компоненты которых имеют те же атрибуты, что и поля экранной формы, ассоциированные с ней;
любыми средствами выбора данных из таблиц (fetch, foreach) заполняется указанный выше программный массив;
с помощью функции set_count() 4GL-программе указывается, сколько строк программного массива заполнено данными и подлежит последующему выводу;
оператором DISPLAY ARRAY выполняется отображение скроллирующего программного массива в экранный массив;
с помощью функций arr_curr(), scr_liпе() в любой момент можно получить номер текущей строки программного и экранного массивов соответственно;
в блоках ON KEY, ассоциированных с DISPLAY ARRAY, при необходимости определяются комбинации клавиш и программные действия, которые должны быть выполнены при нажатии этих клавиш.
Ниже приведен пример отображение данных в экранный массив s_items[5], описанный в экранной форме Example1.per.
Средства организации скроллирующего массива на основе оператора DISPLAY ARRAY могут использоваться для создания вертикального меню. С этой целью организуется экранный массив, состоящий из одного или нескольких полей, и программный массив, содержащий либо фиксированные тексты, либо заполненный элементами строк некоторой таблицы. Функции scr_liпе(), arr_curr() позволяют отслеживать положение курсора на экране и внутри программного массива (пункта меню). С помощью конструкции ON KEY, связанной с оператором DISPLAY ARRAY, выполняется та или иная обработка, которая в общем случае может быть связана с пунктом меню, на котором находится курсор. После выполнения некоторой обработки присходит возврат в вертикальное меню (скроллирующий массив).
Приведенный выше фрагмент 4GL-программы, выполняющий работу с вертикальным меню, использует экранную форму (Scroll.per), в которой описан экранный массив из шести записей.
В отличие от оператора DISPLAY ARRAY, который позволяет лишь отображать скроллирующий массив записей, оператор INPUT ARRAY позволяет менять содержимое записей, удалять их и вставлять новые.
Основные шаги при подготовке экранного массива и использовании оператора INPUT ARRAY те же, что и для оператора DISPLAY ARRAY. Дополнительно отметим возможность включения в этот оператор блоков BEFORE/AFTER INPUT, BEFORE/AFTER FIELD, аналогичных по назначению оператору INPUT и использование функций arr_count() для определения количества заполненных строк в программном массиве. После выполнения оператора INPUT ARRAY с учетом полученного числа строк в программном массиве выполняется обновление строк таблицы, которая ассоциирована с программным массивом.
Ввод данных по оператору INPUT ARRAY так же, как и для INPUT, прерывается нажатием клавиши ESC, либо управляющей клавиши, определенной параметром ACCEPT KEY в операторе OPTIONS. Управляющие клавиши, определенные в параметрах INSERT KEY, DELETE KEY, NEXT KEY, PREVIOUS KEY оператора OPTIONS, служат соответствено для вставки, удаления строк в экранном массиве, а также перемещения страниц вперед и назад.
Ниже приведен фрагмент программы , выполняющей ввод данных в экранный массив s_items[5], описанный в экранной форме Example1.per.
Организация меню в Informix-L
Языковые средства Informix-4GL включают лишь создание кольцевого горизонтального меню для определения вариантов выбора (см. оператор MENU).
Конструкция BEFORE MENU служит для определения блока операторов, выполняемых до активизации меню. Каждый пункт меню начинается ключевым словом COMMAND, с которым могут быть связаны:
ключевое слово KEY и список 'горячих' клавиш (набор одной или нескольких букв, идентификаторов функциональных клавиш или идентификаторов клавиш управления); обозначение клавиш управления при этом имеет вид CONTROL-x, где х - любая буква, кроме A, D, H, L, R, X;
наименование пункта меню (строка, заключенная в кавычки);
строка подсказки, заключенная в кавычки и выводимая во второй строке окна для пояснения назначения пункта меню;
ключевое слово HELP и номер help-сообщения в help-файле, указываемом в операторе OPTIONS и соответствующим варианту меню.
Наименование пункта меню обязательно.
При выборе пункта меню выполняется набор записанных ниже операторов языка Informix-4GL, соответствующих варианту выбора. Дополнительные конструкции CONTINUE MENU, EXIT MENU, NEXT OPTION, SHOW OPTION, HIDE OPTION среди операторов, относящихся к ключевому слову COMMAND, служат соответственно для возврата управления в текущий оператор MENU, выхода из меню, указания следующего пункта меню, отображения либо, наоборот, скрытия пункта меню.
Help-файл представляет собой файл, созданный утилитой mkmessage из предварительно подготовленного текстового файла нижеприведенной структуры (данный файл может одновременно содержать описание сообщений для операторов INPUT, PROMPT, MENU):
. <Номер сообщения>
<Текстовое описание сообщения>
. <Номер сообщения>
<Текстовое описание сообщения>
. . . . . . .
При запуске утилиты mkmessage первым параметром указывается имя текстового файла, вторым - имя формируемого утилитой mkmessage откомпилированного файла. Перед вызовом меню, в котором предполагается использование help-файла, оператором OPTIONS должны быть определены используемый откомпилированный help-файл и способ вызова help-сообщения
OPTIONS HELP FILE "help-файл"
OPTIONS HELP KEY key-name,
где key-name - функциональная либо управляющая клавиша (по умолчанию CONTROL-w).
Организация параллельной работы в СУБД Informix
Необходимость организации параллельной работы с базами данных обусловлена необходимостью разделять одну базу данных несколькими пользователями одновременно. Поэтому, как в любой системе управления параллельной деятельностью, необходимы механизмы упорядочения доступа к ограниченному разделяемому ресурсу со стороны множества параллельных процессов. В процессе организации параллельной работы решаются задачи по достижению двух целей:
установить все блокировки, необходимые для обеспечения целостности данных;
уменьшить, по возможности, число и размеры блокируемых фрагментов, не входя в противоречие с первой целью.
Рассмотрим простейшую ситуацию параллельного выполнения двух программ.
Программа I выбирает строки таблицы базы данных через курсор.
Программа II выполняет обновление тех же строк таблицы.
Возможны следующие четыре варианта последствий, известные как эффекты параллелизма.
Вторая программа заканчивает обновление строк до того, как первая программа выбирает первую строку. В этом случае первая программа показывает только обновленные строки.
Первая программа успевает выбрать каждую строку прежде, чем вторая программа получает возможность ее обновить. В такой ситуации первая программа показывает только исходные строки.
После того, как первая программа выбрала некоторое количество исходных строк, вмешивается вторая программа и приступает к корректировке тех строк, которые первая программа еще не прочитала, и после этого выполняет оператор Commit Work. В этом случае результатом первой программы может быть смесь исходных и обновленных строк.
Случай, аналогичный варианту 3, за исключением того, что после корректировки таблицы вторая программа выполняет оператор Rollback Work. Результатом работы первой программы в этом случае может быть смесь исходных и обновленных строк, которых больше нет (а точнее и не существовало) в базе данных.
Если первые две ситуации вполне безобидные, то две последние (особенно четвертая) не оправданы ни с позиции логики, ни с позиции здравого смысла.
Выделяют два класса параллельности. Первый класс применим в отношении доступа к базе данных на чтение (Select) и называется уровнем изоляции. Второй класс параллельности распространим на операции, модифицирующие базу данных (Insert, Delete, Update).
Организация программы на языке Informix-L
Программа на языке Informix-4GL состоит из одного или нескольких файлов (модулей) с исходными текстами. К ней также относятся файлы с описаниями используемых экранных форм, которые компилируются отдельно. Имя каждого модуля должно иметь расширение .4gl, а имя файла с описанием экранных форм -расширение .per.
Каждый модуль содержит описания переменных и, возможно, несколько процедурных блоков FUNCTION и REPORT (блоки печати). В программе должен быть один блок MAIN - главный блок, начинающийся с ключевого слова MAIN и заканчивающийся END MAIN. На него будет передаваться управление при запуске программы. Для программирования функций (подпрограмм) в языке используется оператор FUNCTION. Все аргументы функции должны быть объявлены. Аргументы передаются по значению. Если функция возвращает какие-либо значения, то при вызове ее нужно воспользоваться в операторе CALL предложением RETURNING с перечислением переменных, в которые возвращаются значения.
Программа на языке Informix-4GL состоит из идентификаторов, ключевых слов, констант, операторов и выражений. Формат записи операторов языка Informix-4GL свободный, подобно языкам С или Pascal. Окончание операторов определяется по контексту и никаких разделителей операторов, таких, как точка с запятой, не требуется, однако некоторые предложения языка, если это необходимо, завершаются ключевым словом END вместе с ключевым словом этого предложения (например, END WHILE или END IF). Комментарии, занимающие несколько строк, ограничиваются знаками "{" и "}", одностроковые комментарии начинаются с символов "#" или "--" и продолжаются до конца строки. Весь набор ключевых слов зарезервирован, их нельзя использовать для других целей. Не делается никаких различий между прописными и строчными буквами.
Программа на языке Informix-4GL оперирует константами, локальными, модульными и глобальными переменными, экранными формами, метками, окнами, функциями и отчетами. За исключением констант, остальные объекты должны именоваться с помощью идентификаторов. Идентификатор представляет собой последовательность длиной до 8 символов, состоящую из букв, цифр и символов "_" и начинающуюся с буквы или символа "_".
Основы программирования на языке Informix-L
В данном разделе описываются такие элементы языка Informix-4GL, как константы, программные переменные, операции, выражения и операторы общего назначения.
Константы
В Informix-4GL допускаются строковые, числовые константы, константы даты и времени. Существуют три предопределенные константы: TRUE=1, FALSE=0, NOTFOUND=100.
Переменным и значениям полей таблиц допускается присваивание значения NULL. Значение NULL отлично от нуля для чисел и от пробелов для строк. Способ его кодирования считается неизвестным для программиста.
Строковая константа - последовательность символов, записанная на одной строке и заключенная в кавычки или апострофы. Для использования в строке двойных кавычек они должны быть удвоены, либо им должен предшествовать знак "\".
Числовые константы записываются в обычной для языков программирования форме, причем только по основанию 10. Допускается экспоненциальная нотация. Константы типа DATA, DATATIME, INTERVAL задаются как с помощью символьных строк, так и специальным образом.
15
654.89
12967.0e-3
"1.01.97"
"Для продолжения нажмите \"Д\""
Типы данных Informix-4GL. Программные переменные
В языке Informix-4GL имеются простые переменные, переменные типа запись и массивы. Для описания всех переменных служит оператор DEFINE, в котором задаются идентификаторы и соответствующие типы данных.
Informix-4GL поддерживает 7 различных представлений числовых данных, некоторые из которых обозначаются более чем одним ключевым словом.
Типы данных | Описание и представление | ||
DECIMAL[(m,n)], DEC[(m,n)], NUMERIC[(m,n)] | Десятичные числа с фиксированной точкой с m (<=32) значащими цифрами, из которых n (<=m) - после запятой | ||
DECIMAL[(m)], DEC[(m)], NUMERIC[(m)] | Десятичные числа с плавающей точкой, лежащие в интервале от 10**(-128) до 10**128 (по умолчанию DECIMAL(16)) | ||
MONEY[(m[,n])] | Денежные суммы с фиксированной точкой, соответствующие DECIMAL(m,n) | ||
FLOAT[(n)],
DOUBLE PRECISION[(n)] |
Двоичные числа с плавающей точкой c точностью, соответствующей double в C | ||
REAL, SMALLFLOAT | Двоичные числа с плавающей точкой c точностью, соответствующей float в C | ||
INT, INTEGER | Целые числа в интервале от -2,147,483,647 до 2,147,483,647 аналогично integer в C | ||
SMALLINT | Целые числа в интервале от -32,767 до 32,767 аналогично short в C |
Informix- 4GL поддерживает следующие типы данных для отслеживания времени.
Типы данных | Описание и представление | |
DATE | Календарные даты, хранимые в виде целых чисел дней, прошедших от 31 декабря 1899 года | |
DATETIME | Моменты времени (дата и время дня), хранимые в виде десятичных чисел с плавающей точкой с нулевой дробной частью и различной точностью, зависящей от требований | |
INTERVAL | Интервалы времени со знаком, прошедшие между двумя значениями DATETIME |
Функция | Описание | |
DAY(date-expr) | Возвращает номер дня месяца от переменных типа DATE или DATETIME | |
MONTH(date-expr) | Возвращает номер месяца от переменных типа DATE или DATETIME | |
WEEKDAY(date-expr) | Возвращает номер дня недели от переменных типа DATE или DATETIME | |
EXTEND(date,quel) | Меняет точность DATE или DATETIME значений, возвращая значение DATETIME | |
YEAR(date-expr) | Возвращает номер года от переменных типа DATE или DATETIME | |
DATE(date-expr) | Преобразует целое или символьную строку в переменную типа DATE или DATETIME | |
MDY(m,d,y) | Строит значение DATE из целочисленных значений месяца, дня, года | |
TODAY | Строит значение DATE с текущим значением даты |
Типы данных | Описание и представление | |
CHAR(n), CHARACTER(n) | Строки фиксированной длины до 32,767 ASCII символов | |
VARCHAR(m) | Строки переменной длины до 256 байт | |
TEXT | Символьные строки до 2**31 байт |
Помимо перечисленных выше простых типов данных Informix-4GL позволяет организовывать записи и массивы. Переменная типа запись описывается при помощи конструкции RECORD . . . END RECORD и включает группу переменных, в общем случае различных типов и возможно другие записи.
Обращение к полю element_name записи record_name производится как record_name. element_name, а ко всем полям записи как record_name.* Конструкции LIKE table.column позволяют определять тип данных в соответствии со значением типа столбца column таблицы table. Если определить запись с помощью конструкции LIKE table.*, то запись будет иметь столько же полей, сколько столбцов в таблице table и таких же типов. Элементами записи могут быть другие записи. Переменная типа массив имеет описатель ARRAY [i,j,k] OF type, где type - тип простой переменной или конструкция RECORD. Ниже приведены примеры определения записей и массивов:
Переменные подразделяются на локальные, модульные и глобальные. Локальная переменная объявлена внутри блока function, main, report. Память под локальные переменные выделяется динамически и определение действует внутри блока, в котором переменная объявлена. Модульная переменная должна быть объявлена в самом начале модуля с исходным текстом вне любого блока report, function или main. Память под модульные переменные выделяется статически и определение действует внутри всего модуля за исключением блоков, в которых это имя переобъявлено и является для них локальным. Глобальные переменные должны быть определены с помощью блока GLOBALS . . . END GLOBALS в этом или отдельном модуле, либо в специальном файле, обращение к которому производится в виде GLOBALS "globals-filename". Для обращения к глобальным переменным в модуле ранее всех программных блоков должно содержаться их определение. Ниже приведен пример описания переменных разных классов и области их действия для программы, состоящей из трех файлов:
Областью действия глобальных переменных, определенных в файле Define.4gl, является вся программа (файлы Define.4gl, Sklad.4gl, Funk.4gl), исключая переменную init_day, которая в функции Funk1 переопределена как локальная. Аналогично областью действия модульных переменных, определенных в файле Sklad.4gl, является весь этот файл, исключая переменную audit, которая в блоке main() переопределена как локальная.
Областью действия идентификаторов форм, окон, функций и отчетов является вся программа. Область действия идентификаторов предложений PREPARE и DECLARE начинается с самого предложения и продолжается до конца модуля.
Операции в языке Informix-4GL
Числовые операции языка Informix-4GL представлены таблицей
+ | сложение | - | вычитание |
* | умножение | / | деление |
** | возведение в степень | mod | деление по модулю |
() | выделение приоритета | USING | форматирование |
time-var + interval-var = time-var;
time-var - time-var = interval-var.
Набор операций и функций для работы со строковыми типами данных и строковых преобразований в Informix-4GL представлен ниже
Операции и функция | Описание | |
char-var, char-var | Конкатенация строк | |
char-var[s,t] | Выделение подстроки значений CHAR или VARCHAR | |
ASCII int-var | Преобразование ASCII-кода в CHAR(1) | |
char-var CLIPPED | Удаление конечных пробелов | |
value USING "format" | Получение символьного представления значения value в соответствии с форматом | |
LENGTH(char-var) | Получение длины символьного выражения, исключая конечные пробелы |
expr1 rel_op expr2 или expr или NOT expr,
где rel_op - операция отношения из следующего набора:
Операция rel_op | Описание | Тип expr | Примечание |
= | Равно | Любой | |
> | Больше | Любой | |
>= | Больше или равно | Любой | |
!=, <> | Не равно | Любой | |
< | Меньше | Любой | |
<= | Меньше или равно | Любой | |
[NOT] LIKE | Вхождение | Символьный | |
[NOT] MATCHES | Вхождение | Символьный | |
IS [NOT] NULL | NULL-значение | Любой | expr2 отсутствует |
При этом Informix- 4GL делает все возможное, чтобы выполнить преобразование типов данных.
Операторы общего назначения
В данном разделе обсуждаются три группы операторов языка Informix-4GL (подробный синтаксис операторов приведен в приложении Г [5]):
операторы присвоения значений;
операторы управления последовательностью выполнения программы;
операторы организации программы.
К первой группе операторов относятся:
LET | Значение, вычисленное в общем случае как результат выражения, присваиваемое простой программной переменной, элементу массива или записи. |
INITIALIZE | Инициализация списка переменных или записи значением NULL или значениями, которые определены как значения по умолчанию для столбцов указанной таблицы. |
Ко второй группе операторов относятся:
СALL | Вызов функции, возвращающей нуль или более значений, указанных в конструкции RETURNING. |
FOR | Заголовок цикла, заканчивающийся предложением END FOR и выполняющийся до тех пор, пока переменная цикла не достигнет предельного значения. |
FOREACH | Заголовок цикла, заканчивающийся предложением END FOREACH и выполняющийся по одному разу для всех строк, возвращенных как результат запроса к базе данных. |
WHILE | Заголовок цикла, заканчивающийся предложением END WHILE и выполняющийся до тех пор, пока условие, сформулированное в заголовке цикла, не станет ложным. |
CONTINUE | Переход к следующей итерации цикла, к следующему пункту меню или к продолжению ввода. |
EXIT | Преждевременный выход из предложений FOR, FOREACH, WHILE, MENU, INPUT, CASE или из всей программы. |
IF | Заголовок условного оператора, заканчивающегося конструкцией END IF. |
CASE | Заголовок оператора выбора, заканчивающегося конструкцией END CASE. |
GOTO | Переход к заранее определенному месту программы на указанную метку. |
LABEL | Определение метки программы для безусловного перехода. |
SLEEP | Задержка выполнения программы на указанный промежуток времени. |
RETURN | Возврат управления из функции, возможно, с возвратом списка выражений, число и типы которых совпадают с обозначенными в предложении RETURNING оператора CALL при вызове функции. |
RUN | Запуск некоторой программы средствами операционной системы. |
К третьей группе операторов относятся:
MAIN | Основной блок программы, на который передается управление при запуске и который заканчивается предложением END MAIN. |
FUNCTION | Программный блок, содержащий последовательность операторов языка Informix-4GL, заканчивающийся предложением END FUNCTION и, возможно, возвращающий вызвавшей ее функции нуль или более значений посредством оператора RETURN. |
REPORT | Блок, содержащий спецификации по выводу и форматированию отчета (см. гл. 4). |
Разработка отчетов в Informix-L
Отчет - документ, формируемый на основе таблиц базы данных или входного файла в формате ASCII. Средства генерации отчетов в Informix-4GL распадаются:
на средства инициализации и управления отчетом;
программу отчета, определяющую его структуру и оформленную как программный блок REPORT.
Список литературы
Ладыженский Г.М. Системы управления базами данных - коротко о главном // Системы управления базами данных. - 1995. - num.1 - С. 128-138.
Никитин В.Д. Система управления базами данных Informix. - Informix Software, Inc. - M., 1994. - 185 c.
Ассонов А.А., Грюнталь А.И. Продукты фирмы Informix// Системы управления базами данных. - 1995. - num.1 - С. 56-61.
Вьюкова Н.И. Продукты Informix и распределенные вычисления // Системы управления базами данных. - 1995. - num.4 - С. 18-29.
Распределенные СУБД. Informix: Метод. указания для выполнения лабораторных работ/ Сост. Стасышин В.М. - Новосибирск: НГТУ, 1997. - Ч 2. Разработка программных приложений средствами встроенного SQL.
Распределенные СУБД. Informix: Метод. указания для выполнения лабораторных работ/ Сост. Стасышин В.М. - Новосибирск: НГТУ, 1997. - Ч 3. Разработка программных приложений средствами языка Informix-4GL.
Язык структурных запросов SQL: Метод. указания по курсу "Базы данных" / Сост. Стасышин В.М. - Новосибирск: НГТУ, 1996.
Распределенные СУБД. Informix. Метод. указания для выполнения лабораторных работ/ Сост. Стасышин В.М. - Новосибирск: НГТУ, 1996. - Ч 1. Основы работы с базами данных.
Informix-4GL. Concepts and Use. Ver 6.0 - 1994. - Part No. 000-7610.
Informix-4GL. Reference: Vol. One. Ver 6.0 - 1994. - Part No. 000-7611.
Informix-4GL. Reference: Vol. Two. Ver 6.0 - 1994. - Part No. 000-7611.
Informix-4GL by Example. : Ver 4.10 - 1991. - Part No. 000-7022.
Informix-4GL. Reference: Ver 6.0 - 1994. - Part No. 000-7607.
Guide to the Informix-4GL. Interactive Debugger. Ver 6.0 - 1994. - Part No. 000-7613.
Структура программы отчета
Программа отчета начинается оператором REPORT, в котором указывается имя и список аргументов, и включает секции DEFINE, OUTPUT, ORDER BY и FORMAT, из них только последняя является обязательной.
В секции DEFINE описываются аргументы, переданные в отчет и локальные переменные отчета. Правила их описаний аналогичны описаниям 4GL-переменных, за исключением того, что параметры отчета не могут быть типа ARRAY, а также записями с членами ARRAY.
Секция OUTPUT
Информация секции OUTPUT используется в момент выполнения оператора Start Report. Ниже приведен формат секции OUTPUT:
[OUTPUT
[
REPORT TO направление вывода:
{
"filename" | - в файл;
PIPE "program"| - на принтер;
PRINTER - в программный канал;
}
]
[LEFT MARGIN integer] левая граница поля;
[RIGHT MARGIN integer] правая граница поля;
[TOP MARGIN integer] верхняяя граница поля;
[BOTTOM MARGIN integer] нижняяя граница поля;
[PAGE LENGTH integer] число строк на странице;
]
Оператор REPORT TO в секции OUTPUT направляет вывод отчета в файл, на системный принтер или в программный канал. Операторы LEFT (RIGTH) MARGIN задают соответственно левую (правую) границу печатной страницы отчета. Операторы TOP (BOTTON) MARGIN устанавливают сколько строк нужно пропустить в начале (в конце) каждой страницы отчета. Оператор PAGE LENGTH устанавливает количество строк на каждой странице отчета.
Секция ORDER BY
Секция ORDER BY специфицирует переменные, по которым необходимо отсортировать строки, передаваемые в отчет (альтернатива к конструкции order by SQL-оператора Select), а также порядок, в котором должны обрабатываться блоки Before group, After group, указанные в секции FORMAT. Сортировка выполняется последовательно по каждому аргументу, указанному в конструкции order by. Дополнительный аргумент EXTERNAL указывает, что строки были ранее отсортированы (на основании конструкции order by SQL-оператора Select) и их не требуется пересортировывать.
Секция FORMAT
Секция FORMAT определяет внешний вид отчета.
Ниже приведен формат секции FORMAT.
FORMAT
{
EVERY ROW | быстрый отчет;
{
{
[FIRST] PAGE HEADER | в начале [первой] страницы;
PAGE TRAILER | в конце страницы;
ON {EVERY ROW | для каждой строки;
LAST ROW} | после последней строки;
{BEFORE | AFTER} перед/после группы.
GROUP OF variable
}
statement . . .
} . . .
}
Самая простая секция FORMAT содержит единственный оператор EVERY ROW и используется для формирования быстрого отчета; в этом случае в секции FORMAT нельзя использовать никакие другие операторы или управляющие блоки.
Более сложные секции FORMAT могут содержать следующие управляющие блоки:
PAGE HEADER control block; | ON LAST ROW control block; |
PAGE TRAILER control block; | BEFORE GROUP OF control block; |
ON EVERY ROW control block; | AFTER GROUP OF control block; |
После перечисленных выше конструкций, открывающих управляющий блок, следует последовательность 4GL-операторов (в том числе и SQL-операторов), 4GL-функций, а также операторов и функций форматирования, которые могут использоваться только в блоке REPORT.
Операторы форматирования секции FORMAT
NEED integer-expr LINES | Начать вывод с новой страницы, если заданное количество строк (LINES) не помещается на текущей странице | |
PAUSE ["string"] | Приостановить вывод в отчет до нажатия клавиши Enter | |
PRINT [integer-list] [;] | Вывести информацию в отчет так, как указано в секции OUTPUT; один оператор PRINT выполняет вывод в одну строку до тех пор, пока не использована конструкция CLIPPED (отсечь пробелы), USING(форматировать) или n SPACES (пропустить n позиций); очередное выражение выводится в поле, ширина которого зависит от типа данных | |
Тип данных | Размер по умолчанию | |
Char | размер Char-переменной | |
Date | 10 | |
Float | 14 (включая знак и десятичную точку) | |
Smallint | 6 (включая знак) | |
Integer | 11 (включая знак) | |
Smallfloat | 14 (включая знак и десятичную точку) | |
Decimal | число цифр + 2 (включая знак и десятичную точку) | |
Serial | 11 | |
Money | число цифр + 3 (включая знак, десятичную точку и знак доллара) | |
PRINT FILE "filename" | Вывод содержимого текстового файла в отчет | |
SKIP {integer-expr LINE[S] | TO TOP OF PAGE} |
Пропуск строк в отчете или переход к началу следующей странице |
Функции форматирования секции FORMAT
[GROUP] указание отображать информацию только для конкретной группы (только в AFTER GROUP OF);
{
COUNT(*) | общее количество строк;
PERCENT(*) | процент от общего числа строк
в отчете;
{SUM | AVG | MIN | MAX} (expression)
сумма, среднее, минимальное, максимальное значение от указанного выражения с игнорированием значения NULL в
выражении;
}
[WHERE Boolean-expr] условие, уточняющее количество строк;
LINENO номер строки отчета;
PAGENO номер страницы отчета;
integer-expr SPACE[S] пропустить указанное число пробелов.
Управляющие блоки PAGE HEADER ( PAGE TRAILER) указывают, какая информация должна появиться в начале (в конце) каждой страницы отчета.
Управление программой отчета
Управление отчетом из 4GL-программы осуществляется с помощью трех операторов: Start Report, Output to Report, Finish Report.
Оператор Start Report идентифицирует отчет (имя программного блока REPORT) и указывает направление выдачи отчета (принтер, файл и пр.), оператор Output to Report используется для выдачи очередной строки (порции данных) в отчет, делая это, как правило, в цикле, оператор Finish Report заканчивает работу с отчетом.
Уровни блокирования
Структурные единицы, которые можно блокировать (ставить замки), отличаются размером блокируемых объектов:
уровень баз данных;
уровень таблиц;
уровень страниц;
уровень строк.
Блокировка на уровне базы данных открывает базу данных в режиме исключающего доступа, предотвращает доступ к ней других пользователей и выполняется посредством оператора Database с опцией Exclusive. Это может быть полезным:
если выполняется большое число модификаций в отношении многих таблиц;
производится архивирование базы данных;
изменяется структура базы данных.
Блокировку на уровне таблиц можно использовать с тем, чтобы предотвратить доступ пользователей для модификации таблицы. Такой уровень логично использовать:
при необходимости устранить конфликты между пользователями при выполнении пакетных операций, которые воздействуют на большинство или на все строки таблицы;
необходимости запрещенияния операций пользователей по модификации таблицы на некотором интервале времени;
необходимости предотвращения доступа к таблице, когда изменяется ее структура или создаются индексы.
В каждый момент времени на таблицу можно поставить только один замок, и если какой-либо пользователь блокирует таблицу, то другие пользователи не могут блокировать ту же таблицу, пока первый пользователь не разблокирут ее.
Если таблица блокирована в разделяемом режиме оператором Lock table с опцией In Share mode, то остальные пользователи будут иметь доступ на чтение в отношение таблицы (выполнять операторы Select), но не смогут выполнять операторы Delete и Update в отношении строк таблицы или Alter в отношении таблицы.
При необходимости предотвратить любую форму доступа к таблице со стороны других пользователей необходимо выполнить блокировку таблицы в режиме исключающего доступа (Lock table с опцией In Exclusive mode).
Informix-Online хранит данные в единицах памяти, называемых дисковыми страницами. Дисковая страница содержит одну или несколько строк.
При создании таблицы производится выбор уровня блокировки, который используется при доступе к любой строке данных. На уровне блокировки страниц (Create table . . . lock mode page) будет блокирована вся страница независимо от того, сколько необходимо реально блокировать строк в ее составе. На уровне блокировки строк (Create table . . . lock mode row) будет блокирована только требуемая строка.
Блокировка на уровне страниц полезна, когда в транзакции выполняется обработка строк в соответствии с индексами таблицы или в соответствии с физическим расположением строк в таблице. Блокировка на уровне строк полезна, когда порядок обработки строк непредсказуем. На уровне блокировки страниц требуется меньше ресурсов, но при этом сужается уровень параллелизма. Если замок ставится на страницу, которая содержит много строк, а другим процессам необходимы данные из той же таблицы, доступ к ним делается невозможным.
Уровни изоляции
Уровень изоляции представляет собой степень изолированности программы от параллельных действий со стороны других программ. Informix-Online предоставляет четыре уровня изоляции:
Dirty Read (грязное чтение);
Committed Read (подтвержденное чтение);
Cursor Stability (чтение по установленному курсору);
Repeatable Read (повторяемое чтение).
Уровень изоляции Dirty Read
Простейший уровень изоляции Dirty Read (грязное чтение)
Set isolation to dirty read
фактически означает отсутствие какой-либо изоляции. Когда программа выбирает строку, она не устанавливает никаких блокировок и просто копирует строки из базы данных, не обращая внимания на то, что делают другие программы.
Если программа, использующая уровень изоляции Dirty Read, считает обновленные строки до того, как обновляющая программа завершит свою транзакцию, а обновляющая программа впоследствии аннулирует ее, то это будет означать, что читающая программа обработала данные, которые никогда не существовали (четвертый эффект параллелизма).
Уровень грязного чтения может быть полезен:
когда таблица является постоянной по содержанию и не меняется;
не требуется стопроцентная точность воспроизведения, а важна скорость доступа к данным и право владения ими;
нет возможности ждать освобождения замков.
Уровень изоляции Committed Read
При использовании уровня изоляции Committed Read (подтвержденное чтение)
Set isolation to committed read
Informix-Online гарантирует, что никогда не вернет строку, не зафиксированную в базе данных. Это предотвращает ситуацию, соответствующую четвертому эффекту параллелизма. Перед выборкой строки сервер проверяет, установил ли обновляющий процесс блокировку этой строки. Поскольку уровень изоляции Committed Read сам не устанавливает блокировки выбранной строки, он почти столь же эффективен, как и уровень Dirty Read. Уровень изоляции Committed Read подходит для использования в тех случаях, когда каждая строка обрабатывается как независимая единица данных без ссылок на другие строки в той же самой или других таблицах и может использоваться:
для просмотров;
запросов;
отчетов, содержащих общую информацию.
Уровень изоляции Cursor Stability
При уровне изоляции стабильное чтение (чтение по установленному курсору)
Set isolation to сursor stability
устанавливается разделяемый замок на каждую строку, когда она выбирается курсором для чтения. Такой замок стоит до тех пор, пока не будет обращения к следующей строке. Если данные выбираются с использованием курсора, то разделяемый курсор сохраняется до выполнения следующего оператора Fetch. На данном уровне изоляции можно не только просматривать подтвержденные строки, но также гарантируется существование строки в то время, когда она просматривается. Никакой процесс не может изменить такую строку (по Update или Delete), пока выполняется ее просмотр. Предложения Select, использующие уровень стабильного чтения, могут быть полезны:
для просмотров,
запросов,
отчетов, содержащих оперативную информацию.
Рассмотрим поведение двух параллельно выполняющихся программ при использовании различных уровней изоляции.
Программа А вставляет новое наименование товара (таблица Stoсk) для некоторого производителя Hero (таблица Manufact). Таблицы связаны между собой по коду производителя. Программа Б намерена удалить производителя Hero и перечень всех товаров, связанных с ним.
Уровень Сursor Stability | Уровень ниже Сursor Stability |
1. Программа А находит по курсору из таблицы Manufact строку, соответствующую Hero, выбирая код производителя и устанавливая совместную блокировку этой строки |
1. Программа А находит по курсору из таблицы Manufact строку, соответствующую Hero, выбирая код производителя и не устанавливая никакой блокировки |
2. Программа Б пытается выполнить оператор Delete для удаления этой строки. Поскольку для этой строки установлена блокировка, сервер баз данных вынуждает программу Б ожидать | 2. Программа Б выполняет оператор Delete для удаления этой строки. Оператор успешно выполняется |
3. Программа А вставляет новую строку с товаром в таблицу Stoсk, используя код производителя, полученный из таблицы Manufact | 3. Программа Б удаляет все строки из таблицы товаров Stoсk, используя код производителя, полученный из таблицы Manufact |
4. Программа А закрывает свой курсор на таблице Manufact, снимая ее блокировку | 4. Программа Б завершает свое выполнение |
5. Программа Б, заканчивая ожидание, завершает удаление этой строки и приступает к удалению строк из таблицы с товарами Stock, которые имеют код производителя Hero, включая строку, только что вставленную программой А |
5. Программа А, которая не знает, что ее копия строки Hero теперь незаконна, вставляет новую строку в таблицу товаров Stock, используя код удаленного производителя Hero |
6. Программа А завершает свое выполнение |
Уровень изоляции Repeatable Read
Set isolation to repeatable read
заставляет сервер баз данных устанавливать блокировку каждой строки, которую выбирает программа в рамках транзакции. Данный уровень изоляции позволяет программам использовать скроллирующий курсор для многократного чтения выбранных строк с гарантией того, что в промежутках времени между чтениями эти строки не будут обновлены или удалены, до тех пор пока не будет сделано подтверждение об окончании транзакции.
В в е д е н и е
Усилия по решению важнейшей задачи информационных систем - хранению и обработке данных, привели к появлению в конце 60 - начале 70-х гг. специализированного программного обеспечения - систем управления базами данных (DataBase Management Systems - DBMS), которые позволяют организовать и структурировать данные для их компьютерной обработки и хранения.
Однако, как справедливо отмечено в [1], представление о СУБД сложилось у большинства отечественных пользователей на основе опыта использования систем на платформе персональных компьютеров таких, как FoxBASE, Paradox, Clipper, dBASE, Clarion, FoxPro и т.д. Причины такой популярности заключаются как в относительной простоте и легкости освоения самих СУБД, так и в практически неограниченных возможностях нелегального копирования программного обеспечения. В результате персональные СУБД используются зачастую для автоматизации таких задач, которые требуют инструментальных средств с качественно иными функциональными возможностями.
Тем не менее уровень развития информационных технологий заставляет задумываться большинство средних и крупных организаций о создании действительно открытых и распределенных информационных систем на основе многопользовательских профессиональных СУБД. К числу таких коммерческих многопользовательских СУБД на сегодняшний день можно отнести
СУБД Oracle фирмы Oracle Corp. (Oracle 6.x, Oracle 7.x и др.);
СУБД Informix фирмы Informix Software. (Informix Online 5.x, Informix Online 7.x и др.);
СУБД Sybase фирмы Sybase Inc. (System 10, System 11);
СУБД Progress фирмы Progress Software Corp. (Progress V7);
СУБД Ingress фирмы Computer Associates (CA-OpenIngress);
СУБД InterBase фирмы Borland.
В рамках любой СУБД функционально можно выделить:
сервер, занимающийся организацией, хранением, поиском данных, их администрированием и защитой;
средства разработки программных приложений.
Сервер любой из перечисленных выше СУБД представляет собой программную компоненту, организация и сложность которой по ряду показателей сравнима с операционной системой [2].
Любая операционная система, будучи универсальной, является эффективной в среднем и не может в полной мере учесть специфики конкретной области применений. Сервер же базы данных, являясь ядром СУБД, использует более эффективные способы организации, хранения и поиска данных (зачастую не пользуясь услугами файловой системы), более эффективные способы управления работами и ресурсами (потоковая архитектура, например).
Являясь специализированным программным обеспечением, СУБД нуждается и в специализированных средствах разработки программных приложений. Спектр средств разработки перечисленных СУБД достаточно широк, начиная от встроенного SQL и библиотек SQL-вызовов до объектно-ориентированных графических программных продуктов по проектированию и разработке приложений баз данных.
Предлагаемое учебное пособие является справочным руководством по языку Informix-4GL, являющимся базовым языком для разработки приложений баз данных в СУБД Informix.
Почему из всего спектра разработки приложений выбран именно Informix-4GL? Во-первых, язык Informix-4GL лежит в основе большинства других средств разработки фирмы Informiх (NewEra, HyperScript и пр.), во-вторых, схожие языковые средства можно найти в других СУБД (Progress 4GL, Ingress/4GL, Sybase 4GL), в-третьих, Informix-4GL, по сути дела, является стандартом языков четвертого поколения для разработки приложений баз данных. Немаловажным является и то обстоятельство, что в отечественной литературе за исключением небольшого числа статей в специальных журналах [2-4] отсутствует систематизированное изложение данного вопроса.
Как язык программирования Informix-4GL обладает несколькими важными свойствами:
является процедурным языком, сохраняя все черты языков третьего поколения;
является непроцедурным языком (языком четвертого поколения) в отношении
- средств доступа к базам данных (посредством SQL-запросов);
- построения отчетов на основе таблиц базы данных и других данных;
- средств построения пользовательского интерфейса с использованием экранных форм, окон и меню;
легок в написании, понимании и поддержке.
Все эти особенности делают Informix- 4GL удобным инструментом для разработки приложений баз данных.
Предлагаемое учебное пособие предназначено для самостоятельного изучения основ языка Informix-4GL в рамках курсов "Базы данных " и "Распределенные базы данных", читаемых студентам специальности 01.02 факультета прикладной математики и информатики.
В первой главе приведены базовые понятия (типы данных, описание структуры программы, набор операторов и конструкций общего назначения) и основные правила программирования на языке Informix-4GL. Описывается система программирования Informix-4GL и инструментарий пользователя при работе с ней. Полный синтаксис операторов языка Informix-4GL приведен в приложениях методических указаний [5-6].
Во второй главе обсуждаются средства общения с базой данных в языке Informix-4GL. При этом предполагается, что слушатели знакомы с языком SQL (Structured Query Language) хотя бы в объеме [7-8]. При этом основной упор делается на обсуждение средств динамического SQL и аппарата курсоров.
Третья и четвертая главы посвящены соответственно описанию средств экранного взаимодействия (экранные формы, окна, меню) и создания отчетов.
В пятой главе обсуждаются вопросы организации параллельной работы в СУБД Informix.
Запросы по образцу
Informix-4GL содержит средства, позволяющие использовать экранную форму и несколько другим путем: помещая литеральные значения и ограничения на значения в поля экранной формы во время выполнения программы, пользователь формирует условия для запроса. Такой процесс называется запросом по образцу (Query-by-example). Оператор CONSTRUCT используется для создания переменной типа Char и формирования булевого выражения, построенного на экранном запросе Query-by-example. Указанный оператор в значительной степени похож на оператор INPUT и содержит список имен столбцов базы данных и список имен полей экранной формы, ассоциированных с этими столбцами. При совпадении имен полей экранной формы и имен столбцов конструкция BY NAME позволяет исключить из оператора CONSTRUCT список имен полей экранной формы. Конструкции BEFORE (AFTER) FIELD, BEFORE (AFTER) CONSTRUCT, ON KEY в операторе CONSTRUCT используются аналогично соответствующим конструкциям оператора INPUT. При вводе параметров поиска Query-by-example необходимо придерживаться следующего синтаксиса:
Символ | Значение | Тип данных | Использование |
= | равно | все | по умолчанию |
> | больше | все | >x |
< | меньше | все | >x |
>= | больше или равно | все | >=x |
<= | меньше или равно | все | <=x |
<> | не равно | все | <>x |
: | диапазон | все | x:y |
* | ноль или больше символов | Char | *x, x*, *x* |
? | один символ | Char | ?x, x?, ?x?, x?? |
. . | диапазон | Datetime, Interval | x . . y |
| | или | все | x | y |
Ввод в поле значения литерала равносильно формированию условия равенства на значение соответствующего столбца.
Ввод данных по оператору CONSTRUCT так же, как и для оператора INPUT завершается нажатием клавиши ESC, либо управляющей клавиши, определенной параметром ACCEPT KEY в операторе OPTIONS, либо нажатием клавиши RETURN после ввода последнего поля экранной формы при условии действия опции INPUT NO WRAP в операторе OPTIONS. В случае опции INPUT WRAP в операторе OPTIONS нажатие клавиши RETURN после ввода последнего поля экранной формы приводит к циклическому перемещению курсора на первое поле экранной формы.
Если после окончания ввода критерия поиска в поля экранной формы ни в одно из полей не введено значений, сформированное условие в текстовой переменной, указанной в операторе CONSTRUCT, имеет вид " 1=1".
На основании введенных данных в поля экранной формы в текстовой переменной, указанной в операторе CONSTRUCT, формируется булевое выражение, которое впоследствии может использоваться при формировании оператора SQL:
к постоянной части оператора SELECT (INSERT, DELETE, UPDATE) после фразы WHERE добавляется условие, хранимое в переменной, указанной в операторе CONSTRUCT;
выполняется оператор PREPARE для составленного текста SQL-оператора;
объявляется курсор для структуры, сформированной в операторе PREPARE;
открывается курсор и оператором FETCH (FOREACH) выполняется чтение строк, удовлетворяющих сформированному запросу.
Отметим два 4GL-оператора общего использования, полезных при разработке программных приложений. Оператор WHENEVER с опциями GOTO, CALL, CONTINUE позволяет определить действия, которые необходимо выполнить в случае возникновения ошибок при исполнении программы. Данный оператор особенно полезен при динамическом формировании операторов, когда в тексте оператора возможны ошибки. Отслеживая состояние системных переменных sqlca.sqlcode и STATUS пользователь сам обрабатывает возникающие ошибки. Значение по умолчанию для ERROR - STOP, для WARNING - CONTINUE. Оператор DEFER запрещает прерывание ввода (обычно DEL или Control-C) и прерывание программы (Control-\).