©Большаков Сергей Алексеевич, к.т.н., доц.,
технический консультант Interface Ltd.
©2002
Данная статья является шестой в цикле статей под общим названием "Изучаем программирование в TD/GUPTA", в котором мы постараемся дать начинающему пользователю программных продуктов ГУПТА всю необходимую информацию для изучения программирования и получения навыков создания информационных систем. В ней мы рассмотрим механизмы работы с записями и таблицами БД на основе двух подходов. Первый основывается на визуальном объекте TD – таблице, а второй на непосредственной работе с выборкой (Result Set). Кроме того, мы поясним возможности отладки программ в TD (программы стали сложнее, и настало для этого время) и способы диагностики ошибок при работе с SQL СУБД. Для успешного усвоения этого материала читателю желательно познакомиться с предыдущими статьями из данного цикла, которые размещены на нашем сайте.
Вы уже можете создавать приложения, работающие с БД. В данной статье мы постараемся расширить Ваши знания о возможностях Gupta Team Developer для решения задач информационных технологий и сформировать практические навыки для такой работы.
Как любые системы программирования TD имеет весь необходимый набор средств для отладки программного обеспечения, поэтому, первоначально, кратко их рассмотрим. Кроме этого в начале статьи мы акцентируем внимание читателей на том, как получить и выдать пользователю программ информацию об ошибках при работе с БД. Такие ошибки не всегда удается исключить в программе, некоторые из них (например, доступ к серверу или конкретной БД) зависят от окружения информационной системы.
Далее будут рассмотрены унифицированные механизмы выборки из БД в визуальную таблицу и способы работы с отдельными записями. Затем остановимся на варианте работы с выборкой из БД (традиционно называемой Result Set - RS) без создания визуальных объектов, и, наконец, покажем, как можно обеспечить навигацию по записям в случае работы с визуальной таблицей и сформированной предварительно выборкой данных из БД.
Для успешного и самостоятельного освоения материала данной статьи, который, мы очень надеемся, может служить своеобразным самоучителем программирования на Gupta TD, желательно познакомиться с материалом и выполнить задания предыдущих статей "Шаг 1-5" .
Team Developer имеет все необходимые средства для отладки информационных систем. Предусмотрены режимы трассировки программ, просмотра переменных, задание точек останова, анимации выполнения программы и останова работы программы. Ниже, на рисунке 1, показаны основные элементы управления отладкой: панель инструментов отладки и меню для управления отладкой. Панель инструментов (Dеbug) становиться доступной при запуске программы. Здесь расположены элементы: запуска и приостановки программы, операции пошагового выполнения программы с входом во вложенную процедуру и без , а также кнопки вызова специальных окон отладки. Эти окна служат для: просмотра переменных, просмотра стека вызова процедур, просмотра управляющих сообщений и просмотра вычислимых выражений. Эти окна мы рассмотрим чуть позже.
Рис. 1 Панель инструментов и меню отладки TD
Меню для управления отладкой содержит следующие позиции: запуск программы в режиме отладки (Go - клавиша F7), останов процесса отладки (Stop – клавиши Shift+F7), приостановка процесса отладки (Break), шаг по программе со входом в процедуры (Step Into – клавиша F10) и с обходом процедур (Step Over – клавиши Ctrl + F10), подменю управления точками останова (Breakpoints) и режимы анимации (No Animate , Slow Animate , Fast Animate). В подменю управления точками останова (на рисунках не показано) предусмотрены следующие возможности: установить точку останова (Toggle – клавиша F9), убрать точку останова (тоже F9), убрать все точки останова (Clear All), временного включения и отключения точек останова (Disable All и Enable All соответственно).
Примечание: 1. Для того чтобы перейти в режим отладчика необходимо первоначально установить одну точку останова, в противном случае программа будет выполняться в автоматическом режиме. Такая точка останова может быть установлена в том месте, где целесообразно начать режим отладки.
2. В отличие от других систем программирования в TD нет необходимости устанавливать специальные переключатели отладки. Так как под управлением TD программа всегда выполняется в режиме интерпретации, то объектных модулей не создается. Ранее мы уже показали ("Шаг 1…") как можно создать исполнимый модуль (*.EXE).
Режимы анимации используются в тех случаях, когда трудно проследить процесс выполнения программы и локализовать ошибки. Применяя этот режим на медленной (Slow) или высокой скорости (Fast) вы можете просматривать последовательность выполняемых операторов SAL и остановить программу в любом месте.
В процессе отладки, находясь в режиме приостановки выполнения программы или при выполнении по шагам, программист может вызвать окно просмотра переменных, показанное ниже. Это окно, помимо вызова его из линейки инструментов, может быть вызвано с помощью комбинации клавиш Alt+5, или посредством меню Tools->Variables.
Рис. 2 Окно просмотра переменных отладчика TD
Окно представляет собой таблицу, в которой даны имена переменных и их значения. Любые изменения переменных в ходе отладки оперативно будут отражаться в этом окне. В нашем примере выводятся переменные: frmPrimer.dfDBName – имя БД, frmPrimer.dfFamReplace – поле окна с фамилией и т.д. Системная переменная lParam содержит информацию передаваемую в процедуру обработки сообщений.
С помощью специальной кнопки (+/-) из этого окна вызывается окно настройки переменных, выводимых в окно просмотра. Это окно показано на рисунке, расположенном ниже. Окно выбора переменных для просмотра имеет интуитивно понятный интерфейс. Оно содержит: три окна списков, одно поле ввода имен переменных и кнопки управления. В двойном списке "Select Watch Variables" устанавливаются области просмотра переменных (окна, процедуры, области OUTLINE и так далее) и конкретные переменный доступные в этих областях. С помощью кнопок "Add" и "Add All", а также двойным щелчком, вы можете переместить переменные в третий список "Current Watch Variables", в котором представлен список переменных, подлежащих выводу в данный момент. Этот список можно очистить полностью (Clear All), или удалить из него одну выделенную строку (Clear). Если идентификатор переменной (можно и без квалифицированной ссылки) вводится вручную в поле "Edit Watch Variable", то после нажатия кнопки "Add" ее имя тоже можно разметить в списке вывода. При необходимости можно отредактировать имя выделенной переменной, для этого используется кнопка "Change". Если вы хотите отказаться от изменений в списке вывода, то используйте кнопку "Cancel", для подтверждения изменений используйте кнопку "Ok".
Рис. 3 Окно выбора переменных для просмотра отладчика TD
Для сложных программ характерен взаимный вызов функций и процедур. Для просмотра последовательности вызова можно использовать окно стека вызова "Call Stack". Это окно показано ниже на рисунке. В списке вызова отражаются вызываемые функции, и процедуры обработки сообщений объектов программы. Ссылка дается квалифицированная, поэтому функция однозначно идентифицируется. Данное окно может активизироваться из линейки отладки, клавишами (Alt+6) или с помощью меню: Tools?>Call Stack.
Рис. 4 Окно стека вызова процедур отладчика TD
Следующее отладочное окно предназначено для просмотра сообщений управляющих программой. Можно включить режим просмотра только пользовательских сообщений SAL (переключатель –"SAM mesages only") или просматривать все сообщения, включая и сообщения WINDOWS (WM_). Последний режим важен, если Вы в программе используете их обработку. Отметим попутно, что можно обрабатывать практически все сообщения WINDOWS и создавать собственные. В окне сообщений отображается: символическое название сообщения (например, SAM_FetchRow), дескриптор оконного объекта, к которому оно адресовано и стандартные параметры (wParam и lParam). Если просмотр сообщений в данный момент не нужен, то его можно отключить ( переключатель – "Stop Watching"). Можно и закрыть все окно, используя панель отладки, клавиши (Alt+7) или с помощью меню: Tools?>Messages. Все управляющие элементы работают в режиме триггера.
Рис. 5 Окно трассировки сообщений отладчика TD
Последнее окно отладчика предназначено для просмотра любых переменных и выражений. Окно "Expressions" представлено ниже. В верхнем списке может быть введено выражение (в нашем случае имя простого поля dfDBName), а в нижнем поле после нажатия кнопки "Eval", формируется текущее значение выражения с указанием типа выражения. В отличии от окна переменных, для получения адекватного значения выражения нужно нажимать кнопку. Вызов данного окна выполняется из панели отладки, клавишами (Alt+8) и меню: Tools?> Expressions.
Рис. 6 Окно просмотра выражений отладчика TD
На следующем рисунке показано, как изменяется вид программы при установке точек останова (Breakpoint). Строка, на которой поставлена точка останова, перекрашивается в красный цвет. Установка и снятие точки останова выполняется клавишей F9 или посредством меню: Debug->BreakPoint->Toggle.
Рис. 7 Точки останова (breakpoint) при отладке в TD
Примечание: 1.При комментировании фрагментов текста точки останова автоматически не удаляются, поэтому их можно сохранять для дальнейшего применения.
2. Нужно иметь вводу, что и при копировании через буфер обмена точки останова тоже копируются.
Если с отладкой программ мы разобрались выше, то с отладкой SQL запросов дела обстоит не так хорошо. Конечно, можно воспользоваться SQLTalk или встроенного DB Explorer для отладки запросов, но это трудно сделать в том случае, когда запросы генерируются в программе. При этом регистрируются ошибка и программа в большинстве случаев завершается. Для обработки этих ситуаций мы уже рассматривали возможности (обработка сообщений SAM_SqlError и оператор When SqlError). При такой обработке можно дать пользователю и разработчику дополнительную информацию, которая может быть получена от TD с помощью специальных функций.
Ниже на рисунке приведен фрагмент программы, демонстрирующей применение таких функций (для локальной обработки ошибок). Функция SqlExtractArgs позволяет получить нужную информацию: стандартные параметры сообщения об ошибках (wParam и lParam), значение курсора, для которого зафиксирована ошибка (hSqlErr), номер ошибки (nErr) и позицию обнаружения ошибки при компиляции запроса (nPos). Курсор может быть использован для отката транзакции (ROLLBACK), номер ошибки и позиция для формирования текста диагностического сообщения. Номер ошибки (nErr) может быть получен также на основе курсора hSql2 с помощью функции SqlError. Другие две функции (SqlGetError и SqlGetErrorText) помогут получить текст сообщения об ошибке. В фрагменте текста для иллюстрации разных возможностей получения информации об ошибке приводим несколько функций, выполняющих одинаковые операции.
Рис. 8 Фрагмент текста обработки параметров локальных ошибок
Примечание: 1. Информация об ошибках получается из файла error.sql, который расположен в корневом каталоге TD. К сожалению, данный файл не русифицирован. Поэтому диагностика получается на английском языке. Однако, если для клиентских приложений в данном файле заменить английские тексты на русские, то система будет автоматически поставлять тексты описания ошибок на русском языке.
2. Можно и в программе предусмотреть русифицированную информацию (файл, массив и так далее) для индикации ошибок для наиболее часто встречающихся ошибок.
3. Если не предусмотрена обработка ошибок и их перехват, то TD формирует собственное окно с информацией об ошибке. В этом случае это будет окно с английскими текстами, что не всегда устраивает разработчиков и пользователей.
При глобальной обработке ошибок мы получим практически такой же текст, который представлен на нижнем рисунке. Данный фрагмент текста завершается вызовом простого специального пользовательского модального окна (dlgError), для выдачи диагностической информации.
Рис. 9 Фрагмент текста обработки параметров глобальных ошибок
Внешний вид данного окна представлен на рисунке, расположенном ниже.
Рис. 10 Пользовательское окно сообщения об SQL ошибках
Окно использует информацию, полученную с помощью функций: SqlExtractArgs и SqlGetErrorText. Информация в диалоговое окно передается с помощью глобальных переменных. Описание объектов диагностического окна дано ниже. Смысл этих переменных понятен из текстов надписей и меток.
Рис. 11 Описание объектов окна сообщений об ошибках
При создании окна диагностики информация из глобальных переменных заносится, как показано ниже, в поля окна при его создании.
Рис. 12 Переменные окна диалога ошибок
Глобальные переменные приложения, описание которых дано ниже, формируются при обработке ошибок.
Рис. 13 Описание глобальных переменных для индикации ошибок
При обработке локальных ошибок первоначально выдается диагностическое сообщение с помощью функции SalMessageBox. Его текст дан ниже.
Рис. 14 Индикация локальной ошибки
При обработке глобальных ошибок также выдается диагностическое сообщение с помощью функции SalMessageBox. Текст сообщения приведен ниже.
Рис. 15 Индикация глобальной ошибки
При индикации ошибки с помощью стандартного параметра lParam (передаваемого обработчику сообщения SAM_SqlError) не всегда формируется правильный код ошибки, так как он упакован, поэтому целесообразно пользоваться функциями SqlExtractArgs и SqlError.
Рис. 16 Индикация ошибки через lParam
Кроме этого, для детального описания ошибочной ситуации можно использовать функцию SqlErrorText. Эта функция имеет пять параметров. Помимо кода ошибки (nErr), нужно указать формат поставляемой информации (режим SQLERROR_Reason – описание ошибки и причина ее возникновения или режим SQLERROR_Remedy – возможные действия по ее преодолению), строка возвращаемого текста (strErrText), максимальная длинна возвращаемого текста и реальная длинна возвращаемого текста. SQLERROR_Reason и SQLERROR_Remedy – являются константами языка SAL. Кстати, режимы SQLERROR_Reason и SQLERROR_Remedy можно и комбинировать, например:
Call SqlErrorText( nErr, SQLERROR_Reason
| SQLERROR_Remedy,
strErrText, 300, nErrLong )
Рассмотрим далее возможности обработки сообщений, которые посылаются таблице при выполнении функции SalTblPopulate. Дело в том, что эта функция выполняет весь набор действий при заполнении таблицы: компиляцию запросов, добавление строк и выборку записей. Иногда необходимо вмешаться в этот процесс, допустим для изменения содержимого заполняемых полей или, например, для нумерации строк таблицы в отдельной колонке. Для того, чтобы внедриться в эти циклы могут быть использованы специальные сообщения, посылаемые таблице при обработке каждой строки. Это следующие сообщения:
SAM_FetchDone – сообщение, посылаемое таблице при завершении ее заполнения,
SAM_FetchRow – сообщение, посылаемое таблице перед формированием строки,
SAM_FetchRowDone – сообщение, посылаемое таблице после формированием текущей
строки.
Для иллюстрации обработки данных сообщений разработано приложение, в котором
созданы процедуры обработки этих сообщений. Окно данного приложения показано
на рисунке ниже.
Рис. 17 Окно приложения для изучения режимов выборки в таблицу
В верхней части окна "Подключение" построены уже известные (по предыдущим статьям) процедуры подключения к БД и отключения от БД. В центральной части расположена таблица "Таблица с проверкой записей", для которой предусмотрены процедуры обработки табличных сообщений. Кнопка "Добавить из БД" инициирует выполнение функции SalTblPopulate для занесения информации в БД в разных режимах (TBL_FillAll, TBL_FillAllBackground, TBL_FillNormal). Отметим, что обработка табличных сообщений зависит от режима. Кнопка "Очистить Таблицу" позволяет удалить все строки таблицы. Скрытое поле "Число строк" показывает число заполненных строк в таблице. В поле "Сообщение обработки" выполняет индикацию последнего сообщения, обработанного в таблице. Для иллюстрации замены полей в таблице предусмотрено специальное поле ввода фамилии. Если это поле заполнено, то при заполнении таблицы все фамилии, совпадающие со значением в этом поле, автоматически будут заменяться на новое значение (три звездочки –"***"). Замена выполняется в процессе заполнения таблицы. Кроме этого при формировании таблицы в первой колонке "№" вычисляется и заполняется номер записи (в БД он отсутствует). Описание основных переменных окна тестового приложения приведено ниже. Здесь можно выделить три курсора (hSql…), переменные счетчики (nCount, nMaxRs и т.д.) и переменную признака подключения. Значение других переменных мы поясним позже.
Рис. 18 Описание переменных окна тестового приложения
Для индикации ошибок и управления доступом к записям опишем глобальные переменные. Их назначение было рассмотрено выше.
Рис. 19 Описание глобальных переменных тестового приложения
Рис. 20 Процедура подключения к БД
В процедуре подключения к БД в тестовом приложении, помимо выполнения уже знакомых функций (SqlConnect, SqlSetIsolationLevel) используются функции включения и отключения доступа к кнопкам, для того чтобы избежать неверных действий (SalDisableWindow, SalEnableWindow). Отметим, что для того, чтобы сократить объем статьи в данном фрагменте описаны и дополнительные действия, которые необходимы для второго приложения статьи и о них мы расскажем позднее. После нормального подключения к БД, а мы с вами используем уже созданную ранее БД COMPANY, на экране должно появиться следующее сообщение.
Рис. 21 Окно сообщения о подключении
При отключении от БД, помимо операции отключения мы должны сделать недоступными кнопки выборки и отключения (pbAddToTabl, pbDisconnect) и включить кнопку поключения (pbConnect), как показано на рисунке ниже.
Рис. 22 Процедура отключения от БД
При небольших выборках из БД целесообразно выполнять заполнение записей в таблицу в режиме TBL_FillAll. В этом случае все записи заносятся в таблицу. Затем программа продолжит работать. В процессе заполнения таблицы для каждой строки будут инициализированы сообщения SAM_FetchRow и SAM_FetchRowDone. Если обработчиков этих сообщений в программе не предусмотрено, то заполнение таблицы выполняется на основе запроса в функции. Если предусмотрен обработчик сообщений SAM_FetchRow, то, во-первых, в этом обработчике необходимо получить запись для занесения в таблицу (функция SqlFetchRow), и, во-вторых, с помощью возврата указать на завершение процесса обработки выборки (Return FALSE) или продолжения выборки (Return TRUE).
Рис. 23 Выборка в таблицу в режиме TBL_FillAll
На следующем рисунке показана процедура обработки сообщения SAM_FetchRow. Поле индикатора (dfIndicator) заполняется названием типа обрабатываемого сообщения (SAM_FetchRow). Колонка таблицы для заполнения номера (colNumb) заполняется значением из iParam увеличенным на единицу, так как нумерация строк идет с нуля. Это значение преобразуется в символьное значение и к нему добавляется точка ("."). Далее из выборки (скрытой в процедурe SalTblPopulate) считывается текущая запись. Код возврата (nRet) определяет режим продолжения заполнения таблицы (FETCH_Ok). В этом случае определяется текущее число строк (dfNumb) и задается код возврата из процедуры (TRUE). Если записи закончились, то закрывается курсор (SqlCommit) и задается код возврата из процедуры (FALSE).
За дополнительной информацией обращайтесь в компанию Interface Ltd.
INTERFACE Ltd. |
|