Совершенствование приложений Oracle Forms

Отладка приложения

Разбить на страницы
Показывать лекцию целиком

Отладка

Разрабатывая приложение, вы так или иначе сталкиваетесь с ошибками выполнения и проектирования формы, идентифицировать которые бывает иногда просто, а иногда очень проблематично. Каждый разработчик знает, что отладка кода может занять существенную часть времени, отведенного на создание приложения. Если вы новичок в Oracle Forms, то для вас выяснение источника ошибки может превратиться в очень долгий и нервный процесс. В этой главе мы познакомимся с представленными Oracle Forms инструментами и встроенными подпрограммами для поиска источника и причины возникновения той или иной ошибки.

Методы отладки

Под методами отладки подразумеваются различные способы выявления причин и источников возникновения ошибок. Мы рассмотрим следующие методы отладки:

  • Отображение отладочных сообщений.
  • Обработка исключительных ситуаций.
  • Компиляция и корректировка кода в редакторе PL/SQL.
  • Работа с Forms Debug Console.
  • Комментарии и сообщения

    Комментарии помогают не только оставлять пояснения к тексту программы, но и комментировать фрагменты программы, помечая ее как невыполнимую часть кода. Комментарии относятся к очень простому методу отладки и используются чаще всего в том случае, когда вы наверняка знаете, где находится ошибка. Если вы не уверены в каком-либо фрагменте кода, вы можете закомментировать этот фрагмент и, вновь запустив программу, проверить, выполняется ли программа дальше или ошибка все же осталась. Вы можете отслеживать ошибку последовательно, комментируя строки программы шаг за шагом. Этот метод хоть и прост, но является довольно трудоемким, когда текст программы очень большой. Также недостатком этого метода является и то, что вам необходимо помнить о том, какие строки нужно обратно раскомментировать. Ниже для сравнения приведено два фрагмента программы, в одном из которых заведомо определена и сключительная ситуация.

    DECLARE 
     Val1 number; 
     Val2 number; 
    BEGIN 
     Val1:=1/0; 
     Val2:=2+3; 
     Message(val2); 
    END;

    Если вы попробуете выполнить вышеописанный пример, то получите ошибку "ORA-01476". Для того чтобы узнать, какой оператор его вызвал, val1 или val2, вам достаточно закомментировать оператор val1 и попробовать выполнить программу снова.

    DECLARE
     Val1 number;
     Val2 number;
    BEGIN
     -- Val1:=1/0; 
     -- место предполагаемой ошибки закомментировано.
     Val2:=2+3;
     Message(val2);
    END;

    Выполнив этот пример, вы увидите, как после комментирования оператора val1 ошибка исчезнет и на экране появится сообщение со значением val2. Вам станет сразу ясно, какая из строк возбуждает исключительную ситуацию.

    Сообщение - это еще один способ отслеживания выполняемого кода программы. Встроенная процедура MESSAGE позволяет вам выводить любое сообщение на экран. Расположив процедуру под наблюдаемым оператором и передав его в качестве параметра, вы можете узнать его значение в ходе выполнения программы. Сообщения могут выводиться в статусной строке формы, для этого свойство "Console Window" формы должно быть правильно настроено, или на экран. В предыдущем примере мы использовали сообщение для вывода на экран значения переменной.

    Сообщения - это одна из самых часто используемых процедур, так как применяется она не только для вывода тематических сообщений пользователю, но и ошибок. Процедура MESSAGE дает гораздо больший эффект, если используется совместно с процедурами SYNCHRONIZE и PAUSE.

    SYNCHRONIZE синхронизирует экран терминала и внутреннее состояние формы, то есть SYNCHRONIZE обновляет вывод на экран (рис. 9.1) для отображения информации, которую Forms имеет в своем внутреннем представлении экрана. Другими словами, SYNCHRONIZE гарантирует вывод сообщения на экран в требуемой точке кода. Ниже приведен пример использования процедуры.

    message('Сообщение 1'); 
    synchronize; 
    message('Сообщение 2'); 
    synchronize; 
    message('Сообщение 3'); 
    synchronize;

    PAUSE синхронизирует вывод на экран и приостанавливает работу приложения до тех пор, пока оператор не нажмет клавишу подтверждения. PAUSE выводит предупреждающее сообщение на экран (рис. 9.2).

    (рис 9.1) Вывод сообщения на экран.(рис 9.2) Сообщение команды PAUSE
    message('Сообщение 1'); 
    PAUSE;

    Что касается ограничений, то здесь нужно заметить, что длина выводимого сообщения не может превышать 200 символов. Не злоупотребляйте сообщениями и не забывайте комментировать отладочные сообщения. Так, например, сообщение, забытое в цикле, может привести к большим неудобствам. Чрезмерное количество сообщений опасно тем, что возникшая ошибка может быть перекрыта вашим сообщением, хотя этого можно избежать, если использовать MESSAGE совместно с командой SYNCHRONIZE.

    Исключительные ситуации

    Исключительные ситуации - это мощная конструкция языка PL/ SQL, позволяющая разработчикам перехватывать и обрабатывать неожиданные и непредвиденные ошибки. Когда мы разрабатываем приложение, мы изначально и заведомо создаем идеальную модель, которая, как нам кажется, не содержит никаких ошибок. Если вы пишете простую программу, которая выдает результат деления двух чисел, вам и в голову не может прийти, что пользователь, работающий с вашей программой, не знает, что на 0 делить нельзя, и как следствие получает ошибку "FRM-40735: WHEN-BUTTON-PRESSED триггер вызвал необработанное исключение ORA - 01476". Ниже приведен рисунок, на котором изображен результат ошибочного действия пользователя, а также сам оператор, возбуждающий исключительную ситуацию (рис. 9.3).

    BEGIN
     :result:=:delimoe/:delitel;
    END;
    (рис 9.3) Деление на ноль

    Обработка исключительных ситуаций

    В вышеописанном примере мы вызываем ошибку ZERO_DIVIDE делением 10 на 0. В этом случае мы получаем сообщение "ORA-01476" без описания причины. Для обработки этой исключительной ситуации добавьте в ваш блок секцию EXCEPTION. В случае возникновения исключительной ситуации будут выполнены операторы, описанные в этой секции, то есть при выполнении программы обработка завершается на операторе, возбудившем исключительную ситуацию, и управление сразу передается в секцию EXCEPTION. Исключительная ситуация может быть обработана в конце любого блока BEGIN-END.

    BEGIN
     :result:=:delimoe/:delitel;
     EXCEPTION
      WHEN ZERO_DIVIDE THEN :delitel:=1; 
    END;

    Вы также можете существенно сократить время на поиск причины ошибки, если обработаете исключительную ситуацию с помощью встроенных функций, которые отразят текст ошибки (рис. 9.4). Так, в предыдущем примере вместо текста "необработанное исключение" вы можете получить текст, дающий полное представление о причине ошибки, то есть "divisor is equal to zero".

    BEGIN 
     :result:=:delimoe/:delitel;
     EXCEPTION
     WHEN ZERO_DIVIDE THEN message(sqlerrm);
    END;
    (рис 9.4) Сообщение об ошибке

    Пользовательские исключительные ситуации

    Сообщение об ошибке типа "ORA-01476: divisor is equal to zero" тоже не является показательным, так как не каждый пользователь знает английский язык, да и фраза "ORA-01476" лишняя. Для того чтобы генерировать собственные сообщения, вы можете определить собственную исключительную ситуацию. Пользовательская исключительная ситуация может быть возбуждена в любом месте блока, в котором она объявлена. Чтобы создать пользовательское исключение, достаточно в секции DECLARE объявить переменную и присвоить ей тип exception. Ниже продемонстрирован пример (рис. 9.5), в котором мы объявляем собственную исключительную ситуацию и заменяем сообщение sqlerrm.

    DECLARE
    myexcept exception; 
    BEGIN 
    IF :delitel =0 THEN
     RAISE myexcept; 
    ELSE :result:=:delimoe/:delitel; 
    END IF; 
    EXCEPTION
     WHEN myexcept THEN 
      message('Деление на ноль. Делитель должен иметь значение, отличное от нуля'); 
    END;
    (рис 9.5) Пользовательская исключительная ситуация

    Связывание исключительной ситуации с кодом ошибки

    Сервер Oracle может связывать определенные исключительные ситуации с кодами стандартных ошибок. Чтобы связать пользовательскую исключительную ситуацию, используйте прагму EXCEPTION_INIT. Ниже приведен пример, в котором показан пример объявления прагмы.

    DECLARE
    myexcept exception;
    pragma exception_init(myexcept,-1476); 
    BEGIN
     :result:=:delimoe/:delitel; 
    EXCEPTION
     WHEN myexcept THEN 
      message('Деление на ноль. Делитель должен иметь значение, отличное от нуля'); 
    END;

    Как вы уже успели заметить, прагма EXCEPTION_INIT в качестве параметров принимает имя исключительной ситуации и код ошибки.

    Процедура RAISE_APPLICATION_ERROR ()

    Процедура RAISE_APPLICATION_ERROR - это еще один способ возбуждения исключительной ситуации, который не требует предварительного объявления и может быть вызван в любом месте блока. Вы можете связать эту исключительную ситуацию с пользовательской исключительной ситуацией, используя прагму EXCEPTION_INIT. Ниже приведен синтаксис процедуры и пример ее использования.

    RAISE_APPLICATION_ERROR    (номер_ошибки,    сообщение, TRUE|FALSE]);

    Номер_ошибки - любое отрицательное число, которое лежит в диапазоне от [-20999, -20000].

    Сообщение - это сообщение, выводимое при возбуждении исключительной ситуации. Максимальный размер текста для выводимого сообщения не должен превышать 2048 символов.

    TRUE | FALSE - этот параметр является необязательным; если его значение истинно, то ошибка добавляется к стеку ошибок, иначе все предыдущие ошибки будут заменены.

    Неименованные исключительные ситуации

    Неименованные исключительные ситуации - это такой вид ситуации, который невозможно предугадать, или ситуация, которая должна произойти, но не представляет для вас особого интереса. Для обработки таких ситуаций существует ключевое слово OTHERS. OTHERS - это обработчик исключительных ситуаций, предназначенный для обработки всевозможных исключительных ситуаций в блоке. Ниже приведен рис. 9.6, демонстрирующий работу обработчика OTHERS.

    (рис 9.6) Обработчик OTHERS

    Функции SQLERRM и SQLCODE

    Встроенные функции SQLERRM и SQLCODE возвращают текст и код ошибки для последней исключительной ситуации (рис. 9.7). Эти функции полезно использовать в обработчике OTHERS, так как они позволяют установить причину возникновения ошибки.

    (рис 9.7) Сообщение SQLERRM и SQLCODE

    DBMS_ERROR_CODE

    Эта функция возвращает номер последней ошибки, возникшей в базе данных. Эта функция не имеет ограничений в использовании. Для рекурсивных ошибок DBMS_ERROR_CODE возвращает код первого сообщения в стеке. Рассмотрим пример, в котором обработаем ошибку ORA-01438 is "value too large for column", но прежде чем приступить к выполнению примера, обратите внимание на синтаксис функции.

    Пример 1. Триггер ON-ERROR. Обработка ошибки

    DECLARE
    eсode NUMBER := ERROR_CODE;
    dbms_ecode NUMBER;
    dbms_etext VARCHAR2(200);
    BEGIN
     IF ecode = 40508 THEN
      Dbms_ecode := DBMS_ERROR_CODE;
      Dbms_etext := DBMS_ERROR_TEXT;
      IF dbms_ecode = -1438 THEN
       Message('Введенное значение превышает допустимое! Введите заново!);
      ELSE
       Message('Вставка не выполнена, так как '||dbmserrtext);
      END IF;
     END IF;

    Обработка NULL - значений

    Несмотря на то что обработчик OTHERS ловит все типичные исключительные ситуации, такую ситуацию, как "невведение данных", он обработать не может. Попробуйте в предыдущем примере оставить поле

    312

    "Делитель" пустым, и вы увидите, что ничего не происходит. Обычно такие ситуации закрываются с помощью настройки определенных свойств элемента. Вы можете установить для поля делитель свойство "Required" равным "True", делая элемент обязательным для ввода. Но можно поступить и по-другому, воспользовавшись функцией NVL, как показано ниже (рис. 9.8).

    DECLARE
    myexcept exception;
    pragma exception_init(myexcept,-1476); 
    BEGIN
     :result:=:delimoe/NVL(:delitel,5); 
    EXCEPTION
     WHEN myexcept THEN message('Деление на ноль. Делитель должен иметь значение, отличное от нуля'); 
    END;
    (рис 9.8) Обработка NULL-значений

    Правильная обработка исключительных ситуаций имеет большое значение для разработчика, сокращая его время на поиск и обработку ошибок, ускоряя отладку приложения.

    Forms Debugger (Debug Console)

    В этом разделе мы познакомимся с более мощным инструментом отладки Oracle Forms - Forms Debugger. Forms Debug Console - это инструмент, который дает разработчику контроль над приложением в режиме отладки и полную информацию о текущем состоянии формы и всех выполняющихся внутри нее операций. Отладчик позволяет вам отслеживать выполнение операторов триггеров и программных модулей пошагово, а также дает вам возможность изменять значение переменных. Исследуя среду выполнения отладчиком, вы получаете возможность ана-

    лизировать переменные, параметры, системные переменные, значения отображаемых и неотображаемых элементов. Инструмент Debug Console (рис. 9.9) имеет простой интерфейс, представляющий собой рабочую область, на которой вы можете наблюдать ход выполнения программы и значения переменных окружения и внутреннего представления Forms. В Debug Console вы можете управлять видимостью разделов, перечисленных ниже, переключая кнопки на горизонтальной панели отладчика:

  • Stack;
  • Variables;
  • Watch;
  • Form Values;
  • PL/SQL packages;
  • Global/System Variables;
  • Breakpoints.
  • (рис 9.9) Debug Console

    Для того чтобы лучше понять принцип работы отладчика, рассмотрим все разделы на примере. Для выполнения примера выполните следующие действия:

  • Создайте форму и назовите ее DEB.fmb.
  • Создайте небазовый блок и разместите в нем одну кнопку.
  • Создайте параметр и установите его свойства: Name=result3, Type=number.
  • Создайте триггер WHEN-BUTTON-PRESSED для кнопки и напишите в нем нижеприведенный код:
    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number;
    value2 number; 
    result1 number; 
    result2 number; 
    result3 number; 
    BEGIN
     value1:=1;
     value2:=2;
     :global.result1:=value1+value2;
     result2:=1/0;
     :parameter.result3:=value2-value1;
    END;
  • Для того чтобы вызвать Forms Debugger, достаточно нажать кнопку Ш "Run Form Debug", которая находится справа от кнопки "Run Form" в верхней горизонтальной панели Forms. Когда вы попробуете запустить форму в режиме отладки, ничего особенного не произойдет, так как форма будет выполняться в привычном для нее режиме до тех пор, пока не встретит точку прерывания программы.

    Breakpoints

    Точка останова - это отметка, сообщающая форме, в каком месте нужно остановить выполнение программы и вызвать отладчик. Точки останова можно устанавливать только на выполняемых операторах, то есть точки останова, установленные на операторах типа begin, end, declare, if вызовут сообщение об ошибке. Точка останова имеет вид красной окружности и устанавливается слева от выполняемого оператора, как показано на рис. 9.10.

    Для того чтобы установить точку останова, щелкните два раза левой кнопкой мыши на левой вертикальной панели PL/SQL-редактора напротив выполняемого оператора. Вы можете установить точку останова, используя один из перечисленных способов:

  • Нажатием клавиши F5. Если точка останова уже существует на этом операторе, то она удаляется.
  • Командой меню Debug | Insert/Remove Breakpoint.
  • Вы можете устанавливать точки останова как перед запуском формы в режиме отладки, так и после запуска. Установите точки останова на операторах value1, value2, :global.result и запустите форму в режиме отладки. Теперь, когда форма запущена и точки останова установлены, перейдем непосредственно к отладке.

    (рис 9.10) Установка точки останова(рис 9.11) Текущая точка останова

    Для того чтобы приступить к отладке, нажмите кнопку в ранее запущенной форме. После того как вы нажмете кнопку, выполнение кода прервется и на самой первой точке останова появится стрелка, означающая текущую точку входа, как показано на рис. 9.11.

    Приступим к рассмотрению разделов Debug Console и начнем с раздела Stack.

    Стек вызова (Call Stack)

    Стек вызова представляет собой цепочку подпрограмм, которая начинается с точки вызова и заканчивается выполняющейся в настоящее время программой. Для того чтобы активировать окно стека, выполните команду Debug | Debug Windows Stack|Stack или нажмите кнопку Stack на панели инструментов Debug Console (рис. 9.12).

    (рис 9.12) Окно "Стек"

    Нажатием кнопки мы инициировали событие WHEN-BUTTON-PRESSED, которое является точкой входа в стек вызовов. Как вы сможете далее увидеть, кадры стека размещаются в порядке их вызова, то есть самый первый вызов будет находиться в нижней части стека, а последний, соответственно, будет самым первым. Название стека кадра состоит из имени модуля, события, элемента и строки вызова.

    Имя_модуля.программная_единица.[имя_блока.имя_элемента]::номер_ строки

    Переменные (Variables)

    Окно Variables (рис. 9.13) предназначено для вывода значений переменных кадра стека. Для того чтобы активировать окно переменных, выполните команду Debug | Debug Windows | Variables или нажмите кнопку Variables на панели инструментов Debug Console.

    (рис 9.13) Окно "Переменные"

    Как видно на рисунке, окно отражает имя, значение и тип переменных стека, а также имя текущего кадра стека в поле "Stack Frame". Чтобы понять, как вам может помочь этот раздел, нажмите кнопку += "Step Into" для вхождения в следующую точку. После перехода в новую точку останова вы увидите, как в поле "Value" отразится значение переменной, то есть 1. Вы можете изменить это значение на любое другое допустимое значение. Модифицирование переменных на этапе отладки дает вам возможность определить, как изменится поведение программы или как повлияет на результат изменение значения той или иной переменной. Исключением являются параметры, значения которых не редактируются и считаются read only. Значения всех не модифицируемых переменных подсвечиваются при попытке изменения.

    Watch (Просмотр)

    Для того чтобы добавить переменную в окно просмотра, выполните следующие действия:

  • Откройте окно "Variables" или "Form Value" и выберите переменную, которую хотите добавить.
  • Нажмите правую кнопку мыши для вызова всплывающего меню и выберите пункт "Add to Watch". После этого в окне просмотра появится выбранная вами переменная, как показано на рис. 9.14.
  • (рис 9.14) Окно "Watch"

    Для того чтобы удалить переменную из окна просмотра, выполните следующие действия:

  • Откройте окно "Watch" и выберите переменную, которую хотите удалить.
  • Вызовите всплывающее меню правым щелчком мыши и выберите пункт "Remove", после чего переменная исчезнет из списка. Чтобы очистить все окно "Watch", выберите пункт "Remove All" всплывающего меню.
  • Form Values (Значения формы)

    Окно "Form Values" отражает значения всех элементов и параметров текущей формы. Для того чтобы активировать окно переменных, выполните команду Debug | Debug Windows | Form Values или нажмите кнопку Form Values на панели инструментов Debug Console.

    Как видно на рис. 9.15, окно содержит две вкладки - "Items" и "Parameters", а также имя текущего модуля в поле "Module". Вкладка "Items" отображает значение элементов блока, а вкладка "Parameters" отображает имя параметра и его значение. Вы можете изменять значения

    (рис 9.15) Окно "Form Values"

    элементов, если они не относятся к числу read only, для тестирования возможных вариантов поведения программы. Например, значение элемента display item нельзя модифицировать.

    PL/SQL Packages (Пакеты PL/SQL)

    Вы можете использовать окно "PL/SQL Packages" для просмотра выполняемого PL/SQL-пакета. В этом окне вы можете отслеживать только переменные пакета, все остальные значения, такие как возвращаемое значение функции и переменные, задействованные в методах тела пакета, будут отображены в окне переменных кадра стека DEB.SPECK_PACK.

    Как показано на рис. 9.16, окно "PL/SQL Packages" состоит из двух столбцов, отображающих имя и значение переменной, и радиогруппы переключателей, управляющих отображением пакетов. Вы можете выбирать, какие пакеты отображать, а какие нет; так, например, выбирая переключатель "Client", вы получите возможность просматривать только клиентские пакеты, то есть те, которые определены непосредственно в модуле формы. Для того чтобы отобразить серверные и клиентские пакеты, нужно выбрать переключатель "All". В поле "Packages" отображается имя текущего пакета, значения переменных которого отображаются в области окна.

    Для того чтобы посмотреть, как отображаются данные в этом окне, создайте простой пакет, скрипт которого приведен в листинге 1.

    PACKAGE speck_pack IS X 
     number:=2;
     FUNCTION a 
      RETURN NUMBER; 
     END; 
     PACKAGE BODY speck_pack IS FUNCTION A 
      RETURN NUMBER IS val number; 
     BEGIN 
      val:=1+2; 
      RETURN X; 
     END; 
    END;
    (рис 9.16) Окно "PL/SQL Packages"

    Добавьте в триггер WHEN-BUTTON-PRESSED новую переменную для вызова функции пакета. Ниже приведен листинг триггера, в котором новые строки выделены жирным шрифтом.

    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number;
    value2 number; 
    result1 number; 
    result2 number;
    result4 number;
    BEGIN
     value1:=1;
     value2:=2;
     result4:=speck_pack.a;
     :global.result1:=value1+value2; 
     --result2:=1/0;
     :parameter.result3:=value2-value1; 
    END;

    Теперь для того, чтобы просмотреть значения переменных пакета во время выполнения формы в режиме отладки, повторите действия, которые мы совершали, рассматривая предыдущие примеры. Для этого запустите форму в режиме отладки, предварительно установив точки останова на операторах value1 и value2, и нажмите кнопку. После того как выполнение кода прервется на операторе value1, продолжите пошаговое выполнение программы, нажимая кнопку "Step Into" до тех пор, пока курсор не попадет на оператор :global.result1. Как только точка входа устанавливается для оператора result4, отладчик перемещает вас в программный модуль пакета и помещает в стек вызовов новый кадр, двигаясь по строкам которого, вы получаете возможность отслеживать состояние глобальных переменных пакета и операторов, задействованных в теле пакета. Заметьте, что новый кадр помещается в верхнюю часть стека.

    Global/System Variables (Глобальные и системные переменные)

    Используйте окно "Global/System Variables" для просмотра значений переменных командной строки, системных и глобальных переменных. Как показано на рис. 9.17, окно "Global/System Variables" состоит из трех вкладок - Global, System и Command Line.

    Для того чтобы просмотреть значение глобальной переменной, нажимайте кнопку "Step Into" до тех пор, пока курсор не покинет оператор :global.result1. Значения глобальных переменных можно изменять, а вот значения переменных Command Line изменять нельзя, так как все они имеют статус read only. Все системные переменные за исключением четырех также имеют статус read only. Системные переменные DATE_ TREASHOLD, EFFECTIVE_DATE, MESSAGE_LEVEL и SUPRESS_ WORKING являются теми самыми исключениями, значения которых можно изменять.

    (рис 9.17) Окно "Global/System Variables"

    Breakpoints (Точки останова)

    Окно "Breakpoints" позволяет не только видеть установленные точки останова, но и управлять ими.

    Как показано на рис. 9.18, вкладка "Breakpoints" отображает три столбца: Source, Enable и Line. Значение, приведенное в столбце "Line", указывает на номер строки, на которой установлена точка останова. Столбец "Source" - это локация точки останова. Вы можете управлять точками останова, делать их активными или неактивными, сбрасывая флаг выключателя. Если флажок сброшен, то точка останова считается неактивной и имеет серый цвет.

    Вкладка "Break On Exceptions" отображает типичные исключительные ситуации, которые могут возникнуть в вашем приложении. Вкладка имеет три столбца, первый из которых позволяет включить или выключить исключительную ситуацию на выбранной точке останова (рис. 9.19). Столбец "Number" отображает код ошибки для исключительной ситуации столбца "Exception Name".

    (рис 9.18) Окно "Breakpoints"(рис 9.19) Вкладка "Break On Exceptions".

    Для того чтобы понять, как установить флажок и вывести на экран сообщение, показанное на рисунке, требуется выбрать точку останова, а затем, перейдя на вкладку "Break On Exceptions", установить флажок на исключительной ситуации с названием "ZERO_DIVIDE". Теперь, когда вы выполнили вышеописанные действия, попробуйте снова пошагово проанализировать код, и вы увидите, что после того как точка входа пре-

    рывания покинет оператор, возбуждающий исключительную ситуацию, на экран выводится сообщение. Чтобы не отслеживать такого рода ошибки, используйте конструкцию EXCEPTION.

    Использование пакета Debug

    Вы также можете управлять отладкой программно, используя встроенный пакет Debug. Рассмотрим некоторые функции этого пакета на конкретных примерах. Для того чтобы установить точку останова программно, добавьте в ваш код строки, приведенные в листинге. Новые строки выделены жирным шрифтом.

    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number;
    value2 number;
    result1 number;
    result2 number; result4 number;
    BEGIN
     value1:=1;
     value2:=2; result4:=speck_pack.a;
     :global.result1:=value1+value2;
     IF Debug.Getn(value2) > 0 THEN raise Debug.Break;
     :parameter.result3:=value2-value1;
    END;

    В этом случае, если значение переменой value2 окажется большим 0, выполнится прерывание.

    Используя процедуру Attach (рис. 9.20) пакета Debug, вы можете перевести форму из нормального режима в режим отладки. После того как вы запустите форму в обычном режиме, нажмите кнопку, и на экране появится сообщение с описанием дальнейших действий.

    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number; 
    value2 number; 
    BEGIN 
     value1:=1;
     value2:=2; 
     DEBUG.ATTACH;
     :global.result1:=value1+value2;
     :parameter.result3:=value2-value1;
    END;
    (рис 9.20) Сообщение Debug.Attach

    Для того чтобы активизировать отладку, выберите пункт главного меню Debug | Attach Debug. В появившемся окне "Attach Debug to" (рис. 9.21) введите имя хоста и номер порта, после чего подтвердите свои действия.

    (рис 9.21) Окно "Attach Debug to"

    Вы можете передать выполнение кода отладчику, подобно тому, как это делает точка останова, используя процедуру Suspend пакета Debug (рис. 9.22).

    (рис 9.22) Процедура Debug.Suspend

    Управление отладкой

    Когда мы нажимали кнопку "Step Into", мы переходили к выполнению следующей строки кода, то есть отлаживали код построчно. Помимо кнопки "Step Into" на панели инструментов Debug имеется еще несколько кнопок для управления ходом отладки. Вы можете воспользоваться пунктами меню Debug (рис. 9.23), действия которых идентичны кнопкам панели управления.

    (рис 9.23) Панель Debug
  • Step Into - шаг внутрь, выполняет следующую строку программы. Построчная отладка полезна в тех случаях, когда вы хотите индивидуально отследить значение каждой строки и попасть в вызываемые подпрограммы.
  • Step Over - пропустить, выполняет следующую строку программы, пропуская при этом вызываемые подпрограммы, что позволяет выполнить подпрограмму, при этом не выполняя ни одной ее строки. Это существенно сокращает время по сравнению с предыдущей командой, так как в программе с большим количеством подпрограмм иногда приходится долго ходить по строкам кода.
  • Step Out - выйти, после выполнения подпрограммы возвращает управление отладчику, останавливаясь в месте вызова подпрограммы. Это действие поможет вам завершить пошаговое выполнение программы.
  • Go - продолжить, выполняет следующую точку останова. После того как все точки останова будут пройдены, нормальное выполнение формы будет возобновлено.
  • Pause - пауза, устанавливает небольшой интервал, после чего снова передает управление отладчику.
  • Stop - остановить, выходит из формы, завершая работу отладчика.
  • Страницы:

    Отладка

    Разрабатывая приложение, вы так или иначе сталкиваетесь с ошибками выполнения и проектирования формы, идентифицировать которые бывает иногда просто, а иногда очень проблематично. Каждый разработчик знает, что отладка кода может занять существенную часть времени, отведенного на создание приложения. Если вы новичок в Oracle Forms, то для вас выяснение источника ошибки может превратиться в очень долгий и нервный процесс. В этой главе мы познакомимся с представленными Oracle Forms инструментами и встроенными подпрограммами для поиска источника и причины возникновения той или иной ошибки.

    Методы отладки

    Под методами отладки подразумеваются различные способы выявления причин и источников возникновения ошибок. Мы рассмотрим следующие методы отладки:

  • Отображение отладочных сообщений.
  • Обработка исключительных ситуаций.
  • Компиляция и корректировка кода в редакторе PL/SQL.
  • Работа с Forms Debug Console.
  • Комментарии и сообщения

    Комментарии помогают не только оставлять пояснения к тексту программы, но и комментировать фрагменты программы, помечая ее как невыполнимую часть кода. Комментарии относятся к очень простому методу отладки и используются чаще всего в том случае, когда вы наверняка знаете, где находится ошибка. Если вы не уверены в каком-либо фрагменте кода, вы можете закомментировать этот фрагмент и, вновь запустив программу, проверить, выполняется ли программа дальше или ошибка все же осталась. Вы можете отслеживать ошибку последовательно, комментируя строки программы шаг за шагом. Этот метод хоть и прост, но является довольно трудоемким, когда текст программы очень большой. Также недостатком этого метода является и то, что вам необходимо помнить о том, какие строки нужно обратно раскомментировать. Ниже для сравнения приведено два фрагмента программы, в одном из которых заведомо определена и сключительная ситуация.

    DECLARE 
     Val1 number; 
     Val2 number; 
    BEGIN 
     Val1:=1/0; 
     Val2:=2+3; 
     Message(val2); 
    END;

    Если вы попробуете выполнить вышеописанный пример, то получите ошибку "ORA-01476". Для того чтобы узнать, какой оператор его вызвал, val1 или val2, вам достаточно закомментировать оператор val1 и попробовать выполнить программу снова.

    DECLARE
     Val1 number;
     Val2 number;
    BEGIN
     -- Val1:=1/0; 
     -- место предполагаемой ошибки закомментировано.
     Val2:=2+3;
     Message(val2);
    END;

    Выполнив этот пример, вы увидите, как после комментирования оператора val1 ошибка исчезнет и на экране появится сообщение со значением val2. Вам станет сразу ясно, какая из строк возбуждает исключительную ситуацию.

    Сообщение - это еще один способ отслеживания выполняемого кода программы. Встроенная процедура MESSAGE позволяет вам выводить любое сообщение на экран. Расположив процедуру под наблюдаемым оператором и передав его в качестве параметра, вы можете узнать его значение в ходе выполнения программы. Сообщения могут выводиться в статусной строке формы, для этого свойство "Console Window" формы должно быть правильно настроено, или на экран. В предыдущем примере мы использовали сообщение для вывода на экран значения переменной.

    Сообщения - это одна из самых часто используемых процедур, так как применяется она не только для вывода тематических сообщений пользователю, но и ошибок. Процедура MESSAGE дает гораздо больший эффект, если используется совместно с процедурами SYNCHRONIZE и PAUSE.

    SYNCHRONIZE синхронизирует экран терминала и внутреннее состояние формы, то есть SYNCHRONIZE обновляет вывод на экран (рис. 9.1) для отображения информации, которую Forms имеет в своем внутреннем представлении экрана. Другими словами, SYNCHRONIZE гарантирует вывод сообщения на экран в требуемой точке кода. Ниже приведен пример использования процедуры.

    message('Сообщение 1'); 
    synchronize; 
    message('Сообщение 2'); 
    synchronize; 
    message('Сообщение 3'); 
    synchronize;

    PAUSE синхронизирует вывод на экран и приостанавливает работу приложения до тех пор, пока оператор не нажмет клавишу подтверждения. PAUSE выводит предупреждающее сообщение на экран (рис. 9.2).

    (рис 9.1) Вывод сообщения на экран.(рис 9.2) Сообщение команды PAUSE
    message('Сообщение 1'); 
    PAUSE;

    Что касается ограничений, то здесь нужно заметить, что длина выводимого сообщения не может превышать 200 символов. Не злоупотребляйте сообщениями и не забывайте комментировать отладочные сообщения. Так, например, сообщение, забытое в цикле, может привести к большим неудобствам. Чрезмерное количество сообщений опасно тем, что возникшая ошибка может быть перекрыта вашим сообщением, хотя этого можно избежать, если использовать MESSAGE совместно с командой SYNCHRONIZE.

    Исключительные ситуации

    Исключительные ситуации - это мощная конструкция языка PL/ SQL, позволяющая разработчикам перехватывать и обрабатывать неожиданные и непредвиденные ошибки. Когда мы разрабатываем приложение, мы изначально и заведомо создаем идеальную модель, которая, как нам кажется, не содержит никаких ошибок. Если вы пишете простую программу, которая выдает результат деления двух чисел, вам и в голову не может прийти, что пользователь, работающий с вашей программой, не знает, что на 0 делить нельзя, и как следствие получает ошибку "FRM-40735: WHEN-BUTTON-PRESSED триггер вызвал необработанное исключение ORA - 01476". Ниже приведен рисунок, на котором изображен результат ошибочного действия пользователя, а также сам оператор, возбуждающий исключительную ситуацию (рис. 9.3).

    BEGIN
     :result:=:delimoe/:delitel;
    END;
    (рис 9.3) Деление на ноль

    Обработка исключительных ситуаций

    В вышеописанном примере мы вызываем ошибку ZERO_DIVIDE делением 10 на 0. В этом случае мы получаем сообщение "ORA-01476" без описания причины. Для обработки этой исключительной ситуации добавьте в ваш блок секцию EXCEPTION. В случае возникновения исключительной ситуации будут выполнены операторы, описанные в этой секции, то есть при выполнении программы обработка завершается на операторе, возбудившем исключительную ситуацию, и управление сразу передается в секцию EXCEPTION. Исключительная ситуация может быть обработана в конце любого блока BEGIN-END.

    BEGIN
     :result:=:delimoe/:delitel;
     EXCEPTION
      WHEN ZERO_DIVIDE THEN :delitel:=1; 
    END;

    Вы также можете существенно сократить время на поиск причины ошибки, если обработаете исключительную ситуацию с помощью встроенных функций, которые отразят текст ошибки (рис. 9.4). Так, в предыдущем примере вместо текста "необработанное исключение" вы можете получить текст, дающий полное представление о причине ошибки, то есть "divisor is equal to zero".

    BEGIN 
     :result:=:delimoe/:delitel;
     EXCEPTION
     WHEN ZERO_DIVIDE THEN message(sqlerrm);
    END;
    (рис 9.4) Сообщение об ошибке

    Пользовательские исключительные ситуации

    Сообщение об ошибке типа "ORA-01476: divisor is equal to zero" тоже не является показательным, так как не каждый пользователь знает английский язык, да и фраза "ORA-01476" лишняя. Для того чтобы генерировать собственные сообщения, вы можете определить собственную исключительную ситуацию. Пользовательская исключительная ситуация может быть возбуждена в любом месте блока, в котором она объявлена. Чтобы создать пользовательское исключение, достаточно в секции DECLARE объявить переменную и присвоить ей тип exception. Ниже продемонстрирован пример (рис. 9.5), в котором мы объявляем собственную исключительную ситуацию и заменяем сообщение sqlerrm.

    DECLARE
    myexcept exception; 
    BEGIN 
    IF :delitel =0 THEN
     RAISE myexcept; 
    ELSE :result:=:delimoe/:delitel; 
    END IF; 
    EXCEPTION
     WHEN myexcept THEN 
      message('Деление на ноль. Делитель должен иметь значение, отличное от нуля'); 
    END;
    (рис 9.5) Пользовательская исключительная ситуация

    Связывание исключительной ситуации с кодом ошибки

    Сервер Oracle может связывать определенные исключительные ситуации с кодами стандартных ошибок. Чтобы связать пользовательскую исключительную ситуацию, используйте прагму EXCEPTION_INIT. Ниже приведен пример, в котором показан пример объявления прагмы.

    DECLARE
    myexcept exception;
    pragma exception_init(myexcept,-1476); 
    BEGIN
     :result:=:delimoe/:delitel; 
    EXCEPTION
     WHEN myexcept THEN 
      message('Деление на ноль. Делитель должен иметь значение, отличное от нуля'); 
    END;

    Как вы уже успели заметить, прагма EXCEPTION_INIT в качестве параметров принимает имя исключительной ситуации и код ошибки.

    Процедура RAISE_APPLICATION_ERROR ()

    Процедура RAISE_APPLICATION_ERROR - это еще один способ возбуждения исключительной ситуации, который не требует предварительного объявления и может быть вызван в любом месте блока. Вы можете связать эту исключительную ситуацию с пользовательской исключительной ситуацией, используя прагму EXCEPTION_INIT. Ниже приведен синтаксис процедуры и пример ее использования.

    RAISE_APPLICATION_ERROR    (номер_ошибки,    сообщение, TRUE|FALSE]);

    Номер_ошибки - любое отрицательное число, которое лежит в диапазоне от [-20999, -20000].

    Сообщение - это сообщение, выводимое при возбуждении исключительной ситуации. Максимальный размер текста для выводимого сообщения не должен превышать 2048 символов.

    TRUE | FALSE - этот параметр является необязательным; если его значение истинно, то ошибка добавляется к стеку ошибок, иначе все предыдущие ошибки будут заменены.

    Неименованные исключительные ситуации

    Неименованные исключительные ситуации - это такой вид ситуации, который невозможно предугадать, или ситуация, которая должна произойти, но не представляет для вас особого интереса. Для обработки таких ситуаций существует ключевое слово OTHERS. OTHERS - это обработчик исключительных ситуаций, предназначенный для обработки всевозможных исключительных ситуаций в блоке. Ниже приведен рис. 9.6, демонстрирующий работу обработчика OTHERS.

    (рис 9.6) Обработчик OTHERS

    Функции SQLERRM и SQLCODE

    Встроенные функции SQLERRM и SQLCODE возвращают текст и код ошибки для последней исключительной ситуации (рис. 9.7). Эти функции полезно использовать в обработчике OTHERS, так как они позволяют установить причину возникновения ошибки.

    (рис 9.7) Сообщение SQLERRM и SQLCODE

    DBMS_ERROR_CODE

    Эта функция возвращает номер последней ошибки, возникшей в базе данных. Эта функция не имеет ограничений в использовании. Для рекурсивных ошибок DBMS_ERROR_CODE возвращает код первого сообщения в стеке. Рассмотрим пример, в котором обработаем ошибку ORA-01438 is "value too large for column", но прежде чем приступить к выполнению примера, обратите внимание на синтаксис функции.

    Пример 1. Триггер ON-ERROR. Обработка ошибки

    DECLARE
    eсode NUMBER := ERROR_CODE;
    dbms_ecode NUMBER;
    dbms_etext VARCHAR2(200);
    BEGIN
     IF ecode = 40508 THEN
      Dbms_ecode := DBMS_ERROR_CODE;
      Dbms_etext := DBMS_ERROR_TEXT;
      IF dbms_ecode = -1438 THEN
       Message('Введенное значение превышает допустимое! Введите заново!);
      ELSE
       Message('Вставка не выполнена, так как '||dbmserrtext);
      END IF;
     END IF;

    Обработка NULL - значений

    Несмотря на то что обработчик OTHERS ловит все типичные исключительные ситуации, такую ситуацию, как "невведение данных", он обработать не может. Попробуйте в предыдущем примере оставить поле

    312

    "Делитель" пустым, и вы увидите, что ничего не происходит. Обычно такие ситуации закрываются с помощью настройки определенных свойств элемента. Вы можете установить для поля делитель свойство "Required" равным "True", делая элемент обязательным для ввода. Но можно поступить и по-другому, воспользовавшись функцией NVL, как показано ниже (рис. 9.8).

    DECLARE
    myexcept exception;
    pragma exception_init(myexcept,-1476); 
    BEGIN
     :result:=:delimoe/NVL(:delitel,5); 
    EXCEPTION
     WHEN myexcept THEN message('Деление на ноль. Делитель должен иметь значение, отличное от нуля'); 
    END;
    (рис 9.8) Обработка NULL-значений

    Правильная обработка исключительных ситуаций имеет большое значение для разработчика, сокращая его время на поиск и обработку ошибок, ускоряя отладку приложения.

    Forms Debugger (Debug Console)

    В этом разделе мы познакомимся с более мощным инструментом отладки Oracle Forms - Forms Debugger. Forms Debug Console - это инструмент, который дает разработчику контроль над приложением в режиме отладки и полную информацию о текущем состоянии формы и всех выполняющихся внутри нее операций. Отладчик позволяет вам отслеживать выполнение операторов триггеров и программных модулей пошагово, а также дает вам возможность изменять значение переменных. Исследуя среду выполнения отладчиком, вы получаете возможность ана-

    лизировать переменные, параметры, системные переменные, значения отображаемых и неотображаемых элементов. Инструмент Debug Console (рис. 9.9) имеет простой интерфейс, представляющий собой рабочую область, на которой вы можете наблюдать ход выполнения программы и значения переменных окружения и внутреннего представления Forms. В Debug Console вы можете управлять видимостью разделов, перечисленных ниже, переключая кнопки на горизонтальной панели отладчика:

  • Stack;
  • Variables;
  • Watch;
  • Form Values;
  • PL/SQL packages;
  • Global/System Variables;
  • Breakpoints.
  • (рис 9.9) Debug Console

    Для того чтобы лучше понять принцип работы отладчика, рассмотрим все разделы на примере. Для выполнения примера выполните следующие действия:

  • Создайте форму и назовите ее DEB.fmb.
  • Создайте небазовый блок и разместите в нем одну кнопку.
  • Создайте параметр и установите его свойства: Name=result3, Type=number.
  • Создайте триггер WHEN-BUTTON-PRESSED для кнопки и напишите в нем нижеприведенный код:
    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number;
    value2 number; 
    result1 number; 
    result2 number; 
    result3 number; 
    BEGIN
     value1:=1;
     value2:=2;
     :global.result1:=value1+value2;
     result2:=1/0;
     :parameter.result3:=value2-value1;
    END;
  • Для того чтобы вызвать Forms Debugger, достаточно нажать кнопку Ш "Run Form Debug", которая находится справа от кнопки "Run Form" в верхней горизонтальной панели Forms. Когда вы попробуете запустить форму в режиме отладки, ничего особенного не произойдет, так как форма будет выполняться в привычном для нее режиме до тех пор, пока не встретит точку прерывания программы.

    Breakpoints

    Точка останова - это отметка, сообщающая форме, в каком месте нужно остановить выполнение программы и вызвать отладчик. Точки останова можно устанавливать только на выполняемых операторах, то есть точки останова, установленные на операторах типа begin, end, declare, if вызовут сообщение об ошибке. Точка останова имеет вид красной окружности и устанавливается слева от выполняемого оператора, как показано на рис. 9.10.

    Для того чтобы установить точку останова, щелкните два раза левой кнопкой мыши на левой вертикальной панели PL/SQL-редактора напротив выполняемого оператора. Вы можете установить точку останова, используя один из перечисленных способов:

  • Нажатием клавиши F5. Если точка останова уже существует на этом операторе, то она удаляется.
  • Командой меню Debug | Insert/Remove Breakpoint.
  • Вы можете устанавливать точки останова как перед запуском формы в режиме отладки, так и после запуска. Установите точки останова на операторах value1, value2, :global.result и запустите форму в режиме отладки. Теперь, когда форма запущена и точки останова установлены, перейдем непосредственно к отладке.

    (рис 9.10) Установка точки останова(рис 9.11) Текущая точка останова

    Для того чтобы приступить к отладке, нажмите кнопку в ранее запущенной форме. После того как вы нажмете кнопку, выполнение кода прервется и на самой первой точке останова появится стрелка, означающая текущую точку входа, как показано на рис. 9.11.

    Приступим к рассмотрению разделов Debug Console и начнем с раздела Stack.

    Стек вызова (Call Stack)

    Стек вызова представляет собой цепочку подпрограмм, которая начинается с точки вызова и заканчивается выполняющейся в настоящее время программой. Для того чтобы активировать окно стека, выполните команду Debug | Debug Windows Stack|Stack или нажмите кнопку Stack на панели инструментов Debug Console (рис. 9.12).

    (рис 9.12) Окно "Стек"

    Нажатием кнопки мы инициировали событие WHEN-BUTTON-PRESSED, которое является точкой входа в стек вызовов. Как вы сможете далее увидеть, кадры стека размещаются в порядке их вызова, то есть самый первый вызов будет находиться в нижней части стека, а последний, соответственно, будет самым первым. Название стека кадра состоит из имени модуля, события, элемента и строки вызова.

    Имя_модуля.программная_единица.[имя_блока.имя_элемента]::номер_ строки

    Переменные (Variables)

    Окно Variables (рис. 9.13) предназначено для вывода значений переменных кадра стека. Для того чтобы активировать окно переменных, выполните команду Debug | Debug Windows | Variables или нажмите кнопку Variables на панели инструментов Debug Console.

    (рис 9.13) Окно "Переменные"

    Как видно на рисунке, окно отражает имя, значение и тип переменных стека, а также имя текущего кадра стека в поле "Stack Frame". Чтобы понять, как вам может помочь этот раздел, нажмите кнопку += "Step Into" для вхождения в следующую точку. После перехода в новую точку останова вы увидите, как в поле "Value" отразится значение переменной, то есть 1. Вы можете изменить это значение на любое другое допустимое значение. Модифицирование переменных на этапе отладки дает вам возможность определить, как изменится поведение программы или как повлияет на результат изменение значения той или иной переменной. Исключением являются параметры, значения которых не редактируются и считаются read only. Значения всех не модифицируемых переменных подсвечиваются при попытке изменения.

    Watch (Просмотр)

    Для того чтобы добавить переменную в окно просмотра, выполните следующие действия:

  • Откройте окно "Variables" или "Form Value" и выберите переменную, которую хотите добавить.
  • Нажмите правую кнопку мыши для вызова всплывающего меню и выберите пункт "Add to Watch". После этого в окне просмотра появится выбранная вами переменная, как показано на рис. 9.14.
  • (рис 9.14) Окно "Watch"

    Для того чтобы удалить переменную из окна просмотра, выполните следующие действия:

  • Откройте окно "Watch" и выберите переменную, которую хотите удалить.
  • Вызовите всплывающее меню правым щелчком мыши и выберите пункт "Remove", после чего переменная исчезнет из списка. Чтобы очистить все окно "Watch", выберите пункт "Remove All" всплывающего меню.
  • Form Values (Значения формы)

    Окно "Form Values" отражает значения всех элементов и параметров текущей формы. Для того чтобы активировать окно переменных, выполните команду Debug | Debug Windows | Form Values или нажмите кнопку Form Values на панели инструментов Debug Console.

    Как видно на рис. 9.15, окно содержит две вкладки - "Items" и "Parameters", а также имя текущего модуля в поле "Module". Вкладка "Items" отображает значение элементов блока, а вкладка "Parameters" отображает имя параметра и его значение. Вы можете изменять значения

    (рис 9.15) Окно "Form Values"

    элементов, если они не относятся к числу read only, для тестирования возможных вариантов поведения программы. Например, значение элемента display item нельзя модифицировать.

    PL/SQL Packages (Пакеты PL/SQL)

    Вы можете использовать окно "PL/SQL Packages" для просмотра выполняемого PL/SQL-пакета. В этом окне вы можете отслеживать только переменные пакета, все остальные значения, такие как возвращаемое значение функции и переменные, задействованные в методах тела пакета, будут отображены в окне переменных кадра стека DEB.SPECK_PACK.

    Как показано на рис. 9.16, окно "PL/SQL Packages" состоит из двух столбцов, отображающих имя и значение переменной, и радиогруппы переключателей, управляющих отображением пакетов. Вы можете выбирать, какие пакеты отображать, а какие нет; так, например, выбирая переключатель "Client", вы получите возможность просматривать только клиентские пакеты, то есть те, которые определены непосредственно в модуле формы. Для того чтобы отобразить серверные и клиентские пакеты, нужно выбрать переключатель "All". В поле "Packages" отображается имя текущего пакета, значения переменных которого отображаются в области окна.

    Для того чтобы посмотреть, как отображаются данные в этом окне, создайте простой пакет, скрипт которого приведен в листинге 1.

    PACKAGE speck_pack IS X 
     number:=2;
     FUNCTION a 
      RETURN NUMBER; 
     END; 
     PACKAGE BODY speck_pack IS FUNCTION A 
      RETURN NUMBER IS val number; 
     BEGIN 
      val:=1+2; 
      RETURN X; 
     END; 
    END;
    (рис 9.16) Окно "PL/SQL Packages"

    Добавьте в триггер WHEN-BUTTON-PRESSED новую переменную для вызова функции пакета. Ниже приведен листинг триггера, в котором новые строки выделены жирным шрифтом.

    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number;
    value2 number; 
    result1 number; 
    result2 number;
    result4 number;
    BEGIN
     value1:=1;
     value2:=2;
     result4:=speck_pack.a;
     :global.result1:=value1+value2; 
     --result2:=1/0;
     :parameter.result3:=value2-value1; 
    END;

    Теперь для того, чтобы просмотреть значения переменных пакета во время выполнения формы в режиме отладки, повторите действия, которые мы совершали, рассматривая предыдущие примеры. Для этого запустите форму в режиме отладки, предварительно установив точки останова на операторах value1 и value2, и нажмите кнопку. После того как выполнение кода прервется на операторе value1, продолжите пошаговое выполнение программы, нажимая кнопку "Step Into" до тех пор, пока курсор не попадет на оператор :global.result1. Как только точка входа устанавливается для оператора result4, отладчик перемещает вас в программный модуль пакета и помещает в стек вызовов новый кадр, двигаясь по строкам которого, вы получаете возможность отслеживать состояние глобальных переменных пакета и операторов, задействованных в теле пакета. Заметьте, что новый кадр помещается в верхнюю часть стека.

    Global/System Variables (Глобальные и системные переменные)

    Используйте окно "Global/System Variables" для просмотра значений переменных командной строки, системных и глобальных переменных. Как показано на рис. 9.17, окно "Global/System Variables" состоит из трех вкладок - Global, System и Command Line.

    Для того чтобы просмотреть значение глобальной переменной, нажимайте кнопку "Step Into" до тех пор, пока курсор не покинет оператор :global.result1. Значения глобальных переменных можно изменять, а вот значения переменных Command Line изменять нельзя, так как все они имеют статус read only. Все системные переменные за исключением четырех также имеют статус read only. Системные переменные DATE_ TREASHOLD, EFFECTIVE_DATE, MESSAGE_LEVEL и SUPRESS_ WORKING являются теми самыми исключениями, значения которых можно изменять.

    (рис 9.17) Окно "Global/System Variables"

    Breakpoints (Точки останова)

    Окно "Breakpoints" позволяет не только видеть установленные точки останова, но и управлять ими.

    Как показано на рис. 9.18, вкладка "Breakpoints" отображает три столбца: Source, Enable и Line. Значение, приведенное в столбце "Line", указывает на номер строки, на которой установлена точка останова. Столбец "Source" - это локация точки останова. Вы можете управлять точками останова, делать их активными или неактивными, сбрасывая флаг выключателя. Если флажок сброшен, то точка останова считается неактивной и имеет серый цвет.

    Вкладка "Break On Exceptions" отображает типичные исключительные ситуации, которые могут возникнуть в вашем приложении. Вкладка имеет три столбца, первый из которых позволяет включить или выключить исключительную ситуацию на выбранной точке останова (рис. 9.19). Столбец "Number" отображает код ошибки для исключительной ситуации столбца "Exception Name".

    (рис 9.18) Окно "Breakpoints"(рис 9.19) Вкладка "Break On Exceptions".

    Для того чтобы понять, как установить флажок и вывести на экран сообщение, показанное на рисунке, требуется выбрать точку останова, а затем, перейдя на вкладку "Break On Exceptions", установить флажок на исключительной ситуации с названием "ZERO_DIVIDE". Теперь, когда вы выполнили вышеописанные действия, попробуйте снова пошагово проанализировать код, и вы увидите, что после того как точка входа пре-

    рывания покинет оператор, возбуждающий исключительную ситуацию, на экран выводится сообщение. Чтобы не отслеживать такого рода ошибки, используйте конструкцию EXCEPTION.

    Использование пакета Debug

    Вы также можете управлять отладкой программно, используя встроенный пакет Debug. Рассмотрим некоторые функции этого пакета на конкретных примерах. Для того чтобы установить точку останова программно, добавьте в ваш код строки, приведенные в листинге. Новые строки выделены жирным шрифтом.

    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number;
    value2 number;
    result1 number;
    result2 number; result4 number;
    BEGIN
     value1:=1;
     value2:=2; result4:=speck_pack.a;
     :global.result1:=value1+value2;
     IF Debug.Getn(value2) > 0 THEN raise Debug.Break;
     :parameter.result3:=value2-value1;
    END;

    В этом случае, если значение переменой value2 окажется большим 0, выполнится прерывание.

    Используя процедуру Attach (рис. 9.20) пакета Debug, вы можете перевести форму из нормального режима в режим отладки. После того как вы запустите форму в обычном режиме, нажмите кнопку, и на экране появится сообщение с описанием дальнейших действий.

    WHEN-BUTTON-PRESSED
    DECLARE
    value1 number; 
    value2 number; 
    BEGIN 
     value1:=1;
     value2:=2; 
     DEBUG.ATTACH;
     :global.result1:=value1+value2;
     :parameter.result3:=value2-value1;
    END;
    (рис 9.20) Сообщение Debug.Attach

    Для того чтобы активизировать отладку, выберите пункт главного меню Debug | Attach Debug. В появившемся окне "Attach Debug to" (рис. 9.21) введите имя хоста и номер порта, после чего подтвердите свои действия.

    (рис 9.21) Окно "Attach Debug to"

    Вы можете передать выполнение кода отладчику, подобно тому, как это делает точка останова, используя процедуру Suspend пакета Debug (рис. 9.22).

    (рис 9.22) Процедура Debug.Suspend

    Управление отладкой

    Когда мы нажимали кнопку "Step Into", мы переходили к выполнению следующей строки кода, то есть отлаживали код построчно. Помимо кнопки "Step Into" на панели инструментов Debug имеется еще несколько кнопок для управления ходом отладки. Вы можете воспользоваться пунктами меню Debug (рис. 9.23), действия которых идентичны кнопкам панели управления.

    (рис 9.23) Панель Debug
  • Step Into - шаг внутрь, выполняет следующую строку программы. Построчная отладка полезна в тех случаях, когда вы хотите индивидуально отследить значение каждой строки и попасть в вызываемые подпрограммы.
  • Step Over - пропустить, выполняет следующую строку программы, пропуская при этом вызываемые подпрограммы, что позволяет выполнить подпрограмму, при этом не выполняя ни одной ее строки. Это существенно сокращает время по сравнению с предыдущей командой, так как в программе с большим количеством подпрограмм иногда приходится долго ходить по строкам кода.
  • Step Out - выйти, после выполнения подпрограммы возвращает управление отладчику, останавливаясь в месте вызова подпрограммы. Это действие поможет вам завершить пошаговое выполнение программы.
  • Go - продолжить, выполняет следующую точку останова. После того как все точки останова будут пройдены, нормальное выполнение формы будет возобновлено.
  • Pause - пауза, устанавливает небольшой интервал, после чего снова передает управление отладчику.
  • Stop - остановить, выходит из формы, завершая работу отладчика.
  • Вернуться к учебному плану