ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



+                           EГЛАВАF E6F
                   EСоздание и Описание БлоковF
  Формы,которые вы разрабатываете с помощью SQL*Forms,компонуются из блоков,
соответствующих каждый (максимум) одной таблице БД.Эта глава объясняет,как:
 * создавать блок по умолчанию
 * создавать блок пользователя
 * определить,каким образом будет выполняться запрос
 * определить другие свойства блока

                           EСоздание блокаF
                          EОкно CHOOSE BLOCKF
   Создание нового блока в форме начинается с окна CHOOSE BLOCK.Это окно по-
является,когда вы выбираете из окна CHOOSE FORM опции CREATE или MODIFY,или
когда вы нажимаете клавишу [Accept] для возврата из экранного построителя
форм.
 1.Name(имя): В этой области ввода задается имя блока.
        Если вы планируете создать блок по умолчанию,то имя блока будет поя-
    вляться в верхней части блока; таким образом,выбрать имя - значит выбра-
    ть соответствующий заголовок.(Если захотите,вы всегда сможете изменить
    его в экранном построителе форм.)
 2.Page Number(номер страницы): В этой области ввода указывается N страницы,
   с которой вы желаете работать в данной форме.Хотя блок охватывает все ст-
   раницы формы,обычно удобнее объединять все поля блока на одной странице.
 3.Для того,чтобы создать блок по умолчанию,в котором поля компонуются и по-
   мечаются автоматически,выбирается DEFAULT.
 4.Для того,чтобы создать блок пользователя,в котором с помощью экранного
   построителя вы хотите разместить и пометить поля,необходимо выбрать
   CREATE.
        Даже если вы не хотите делать блок строго по умолчанию,в любом слу-
чае,для создания блока часто бывает более удобным использование DEFAULT.За-
тем вы можете перейти в экранный построитель и модифицировать структуру бло-
ка по умолчанию без необходимости выполнять все действия по определению ст-
руктуры самому.

                    EСоздание блока по умолчаниюF
    Выбор для создания блока по умолчанию вовсе не означает,что вы не можете
вмешаться в этот процесс.Вы можете самостоятельно решить:
 * какую таблицу представляет блок
 * какие столбцы из таблицы будут включены в работу
 * сколько строк будет отображаться одновременно
 * в каком месте страницы будет расположен блок
   Рисунок 6-2 показывает два типичных блока по умолчанию - первый отобража-
ет одиночную запись,другой отображает несколько записей - на одну страницу
формы-примера.

                        EОкно DEFAULT BLOCKF
   При выборе DEFAULT BLOCK из окна CHOOSE BLOCK будет отображаться окно
DEFAULT BLOCK,показанное на рис.6-3.
   Для создания блока по умолчанию:
 1.Table Name(имя таблицы): В этой области ввода укажите имя таблицы,записи
   которой вы хотите отобразить в блоке.По умолчанию SQL*Forms предполагает,
   что таблица имеет имя,совпадающее с именем блока; если это не так,необхо-
   димо изменить имя.
        Если вы не уверены,какая из таблиц вам нужна,выберите TABLES для
   отображения окна LIST TABLES,которое содержит список имеющихся в наличии
   таблиц.
 2.Rows Displayed(отображаемые строки): В этой области ввода задайте количе-
   ство одновременно отображаемых записей.Вы можете создать моноблок (где по
   умолчанию со держиться одна строка) или мультиблок (с более,чем одной ст-
   рокой).
        Если вы хотите знать,какое число записей является максимальным для
   страницы,выберите COLUMNS для высвечивания окна SELECT COLUMNS.Затем наж-
   мите [Accept] для возврата в окно DEFAULT BLOCK,где появиться новая стро-
   ка - Maximum Rows ("максимальное число строк").
        По умолчанию мультиблок должен занимать одну страницу и все его поля
   располагаются в одной строке.Если не хватает места для всех записей на
   странице,можно указать меньшее число записей или расположить блок на дру-
   гой странице.Если все поля не умещаются на одной строке,вы можете опусти-
   ть некоторые поля или создать моноблок (см.примечание в разделе "Окно
   SELECT CLOUMNS").
 3.Base Line(базовая строка): В этой области ввода задайте N строки экрана,с
   которой вы хотите начать блок.По умолчанию это первая пустая строка после
   всех уже существующих в форме,однако вы можете изменить это значение (до
   14 - для моноблока или до 17 - для мультиблока).
        SQL*Forms будет выдавать сообщение,если ваша базовая строка мультиб-
   лока не предоставляет достаточного пространства для размещения всех запи-
   сей на странице.
 4.Если вы хотите отобразить все столбцы таблицы,необходимо просто нажать
   [Accept].SQL*Forms будет создавать блок и выполнять возврат в окно CHOOSE
   BLOCK.При желании,для просмотра блока в экранном построителе форм,можно
   выбрать MODIFY.
         Если вы хотите выбрать столбцы для блока,используйте для этого
COLUMNS; появиться окно SELECT COLUMNS,где можно выбрать столбцы для отобра-
жения их на экране терминала.

                         EОкно SELECT COLUMNSF
   Выбор COLUMNS из окна DEFAULT BLOCK приводит к высвечиванию окна SELECT
COLUMNS.Оно содержит список столбцов таблицы,которую вы выбрали для текущего
блока.По умолчанию выбираются все столбцы,однако это можно изменить несколь-
кими способами:
 * переместив курсор к какому-либо столбцу и нажав [Select] для его исключе-
   ния (при изменении своих намерений снова нажмите [Select])
 * выбрав NONE для исключения всех столбцов
 * выбрав ALL для повторного выбора всех столбцов
 * если перечень столбцов не умещается в одном окне,выбрав NEXT для отобра-
   жения следующей страницы и PREVIOUS - для отображения предыдущей.
       Когда вы удовлетворены выбором столбцов,нажмите [Accept] для возврата
в окно DEFAULT BLOCK.Вы заметите,что SQL*Forms добавил к окну строку,помече-
нную как "Maximum Rows".Это показывает вам - в зависимости от выбранных сто-
лбцов - наибольшее количество строк,которые могут располагаться на странице
мультиблока.Если все поля не будут помещаться в одной строке,максимумом бу-
дет единица (это означает,что блок по умолчанию м.б. моноблоком).
   Примечание: Имеется 2 возможности для создания мультиблока,все поля кото-
               рого не помещаются на одной строке :
               * использовать окно DEFINE FIELD,описанное в главе 7,для уме-
                 ньшения ширины полей так,чтобы все поля помещались в одной
                 строке; или
               * использовать окно DEFINE BLOCK,описанное в этой главе,чтобы
               назначить для размещения каждой записи более,чем одну строку.
   В любом случае,лучше всего продолжать создавать мультиблок по умолчанию,
выбирая столько столбцов,сколько можно разместить в одной строке.Затем нужно
войти в экранный построитель форм,уменьшить ширину столбца или добавить до-
полнительные строки,и,затем,добавить дополнительные поля.Когда вы удовлетво-
рены спецификацией блока,нажмите [Accept].SQL*Forms при этом создаст блок и
возвратит окно CHOOSE BLOCK.При необходимости просмотреть новый блок в экра-
нном построителе форм в этом окне нужно выбрать MODIFY.

                EКак SQL*Forms создает блок по умолчаниюF
   Для блоков по умолчанию SQL*Forms имеет следующие спецификации,показанные
на рис.6-2:

                              Структура блока
 * В верхней части каждого блока имеется заголовок,состоящий из пустой стро-
   ки,имени блока (в качестве контанстантного текста) и еще одной пустой
   строки.Поля и метки полей располагаются в моноблоке или мультиблоке в со-
   ответствии с порядком их расположения в БД.
 * Поля моноблока располагаются согласно английскому порядку чтения,по 2 на
   строке,с двумя областями ввода,начинающихся соответственно с позиций 20 и
   60.Любое поле длиной более,чем 20 символов,занимает 20 позиций выделенной
   области ввода и продолжается далее на оставшихся позициях невыделенной
   области ввода.Названия полей располагаются слева от поля.
 * Поля в мультиблоке располагаются в одной строке экрана слева направо,с
   одной,двумя или тремя пустыми позициями между полями.Последовательные за-
   писи появляются в последовательных строках (которые не показываются на
   экране).Название каждого поля отображается над полем.Если поля не помеща-
   ются в одной строке,SQL*Forms не будет пытаться отобразить более одной
   записи блока.
 * Названия любых полей являются именами соответствующих столбцов таблицы.
   Название может усекаться,если имя столбца больше,чем длина области отоб-
   ражения полей.

                                 Внешний вид полей
 * Каждое поле имеет такой же тип (CHAR,DATE или NUMBER),как и соответствую-
   щий столбец таблицы.
 * Длина поля (размер данных или формат хранения на диске) типа CHAR являет-
   ся шириной соответствующего столбца таблицы.
 * Ширина вывода (изображение символов на экране терминала) поля типа CHAR
   совпадает с длиной поля вообще (максимум до 60 знаков).Если длина поля
   превышает 60 позиций,то для просмотра всего значения необходимо использо-
   вать горизонтальное перемещение.
 * Для поля типа DATA и длина поля и ширина вывода равны 9.
 * Длина поля типа NUMBER на 2 больше,чем ширина соответствующего столбца
   таблицы (2 дополнительные позиции отводятся для десятичной точки и знака
   "-" (минус)).Если ширина столбца не определе на явно,то длина поля прини-
    мается равной 44.
         Ширина вывода поля типа NUMBER является такой же,как и длина самого
поля (максимальное значение равно 10).Если длина поля больше,чем 10,поле м.б.
"прокручено" для показа всего значения (горизонтальное перемещение).
 * Для каждого поля по умолчанию выбираются следующие атрибуты (см."Окно
   SPECIFY ATTRIBUTES" в главе 7):
 * Databse Field (поле БД)
 * Displaied (отображаемое)
 * Input allowed (ввод разрешен)
 * Query allowed (запрос разрешен)
 * Update allowed (корректировка разрешена)
     Если соответствующий столбец таблицы имеет параметр NOT NULL,также вы-
   бирается атрибут "Mandatory".Все другие атрибуты исключаются.
 * Сообщение-подсказка для каждого поля имеет вид:
                                    Enter value for: fieldname(имя поля)

                       EСоздание блока пользователяF
   Когда вы выбрали CREATE из окна CHOOSE BLOCK,вы сразу же перейдете в эк-
ранный построитель форм.В самом начале блок является пустым.Вы можете:
 * перемещать курсор по экрану
 * вводить и редактировать константный текст
 * создавать и определять поля текущего блока
 * определять текущий блок
 * чертить рамки и линии
   Экранный построитель форм подробно описан в гл.5 данного документа.Когда
вы закончите формировать блок,нажмите [Accept] для возврата в окно CHOOSE
BLOCK.

                             EОпределение блокаF
   Определить блок - значит задать его характеристики,показывающие:
 * к какой таблице он относится
 * как с ним взаимодейтсвует оператор
 * как запросы выполняются
 * как отображаются его строки
 * как проверяются данные его строк
 * какие триггеры он активизирует
   Когда вы создаете блок,по умолчанию ли,или блок пользователя,все его ха-
рактеристики имеют значения по умолчанию,заданные посредством SQL*Forms.Вам
необходмио определить блок,только если вы хотите изменить эти значения.
   Окна,используемые для определения блока,показаны на рис.6-5:
          Ъ--------------------------------ї
          і ЭКРАННЫЙ ПОСТРОИТЕЛЬ ФОРМ      і
          А----------В--------------------ДЩ
     [Select Block]  і   ^
        +[Define]    і   і
                     і   і
                     v   і [Accept]
     УПОРЯДОЧЕНИЕЪ--------------Б----ї
    Ъ------------ґ  ОКНО             і<------Дї
    і     Ъ----Д>і DEFINE BLOCK      Г----ї Т і
    і     і      А------В------------Щ    і Р і
    і     і        ОПЦИИі             ^   і И і
    і     і             і             і   і Г і
    і     і             і             і   і Г і
    і     і             і             і   і Е і
    і     і             і             і   і Р і
    v     і[Accept]     v   і[Accept] v   і [Accept]
----------Б----ї Ъ----------Б----ї Ъ------Б--------ї
  ОКНО         і і         ОКНО  і і  ОКНО         і
SPECIFY DEFAULTі і SPECIFY BLOCK і і CHOOSE TRIGGERі
 ORDERING      і і OPTIONS       і і (см.главу 8)  і
--------------ДЩ А--------------ДЩ А--------------ДЩ
      Рис.6-5.Определение блока

                          EОкно DEFINE BLOCKF
   Чтобы определить блок,войдите в экранный построитель форм,укажите имя
блока и N страницы,и выберите MODIFY из окна CHOOSE BLOCK.Затем нажмите
[Select Block] и [Define].Вы увидите окно DEFINE BLOCK,показанное на рис.
6-6.
                            Определение блока:
 1.Seq #(порядковый N): В этой области ввода показывается порядок перемеще-
   ния курсора по данному блоку при нажатии оператором клавиш [Next Block]
   или [Previous Block].Для уточнения деталей см."Изменение порядка следова-
   ния" в главе 4.
 2.Name(имя): Если вы используете эту область ввода для переименования бло-
   ка,помните,что триггеры,связанные с блоком,станут недействительными; вы
   должны сами найти триггеры и изменить ссылки.
 3.Description(описание): В этой области ввода указывается краткое описание
   блока,которое появляется,когда оператор нажимает [Menu] (при желании,мож-
   но совсем удалить "Description" из окна, используя окно SPECIFY BLOCK
   OPTIONS).
 4.Table Name(имя таблицы): В этой области ввода указывается имя таблицы или
   экранной формы,связанной с блоком.Для блока по умолчанию вы можете игно-
   рировать эту область ввода,так как имя,заданное вами при создании блока,
   уже находится в области ввода.Для блока пользователя значением по умолча-
   нию является имя блока; необходимо изменить это имя,если оно отличается
   от имени таблицы.
        Если вы не уверены,какая из таблиц вам нужна,выберите TABLES для вы-
   вода на экран окна LIST TABLES,которое содержит список существующих таб-
   лиц.
        Чтобы определить управляющий блок,который не связан с какой-либо та-
   блицей,нужно выполнить "пустой" ввод (т.е.заменить имя пробелами).
 5.Чтобы определить триггеры блока (это необязательно),выберите TRIGGER для
   отображения окна DEFINE TRIGGER.Триггеры уровня блока объясняются в этой
   главе ниже.
 6.Чтобы управлять процессом выборки записей в блок при выполнении запросов
   (также необязательно),выберите ORDERING для отображения окна SPECIFY
   DEFAULT ORDERING,описанного в следующей части.
 7.Чтобы управлять отображением и проверкой данных записей (необязательно),
   выберите OPTIONS из окна SPECIFY BLOCK OPTIONS,описанного в этой главе
   ниже.
       Когда вы удовлетворены указанными характеристиками блока,нажмите
[Accept] для сохранения ваших изменений и возврата в экранный построитель
форм.В противном случае,чтобы аннулировать внесенные вами изменения,нажмите
[Exit/Cancel].

                      EОкно SPECIFY DEFAULT ORDERINGF
   После того,как вы выбрали ORDERING из окна DEFINE BLOCK,вы увидите окно
SPECIFY DEFAULT ORDERING, показанное на рис.6-7.В нем вы можете определить
умолчание для фраз WHERE и/или ORDER BY,чтобы включить их в каждый запрос
блока.
   Окно SPECIFY DEFAULT ORDERING состоит только из одной большой области
ввода,где вы можете вводить свои фразы WHERE и ORDER BY.Фраза WHERE устанав-
ливает условия,которым должны удовлетворять выбираемые запросом строки таб-
лицы.Фраза ORDER BY определяет порядок,в котором строки выбираются и далее
представляются в блоке.
   Например,посмотрите условие упорядочения для блока ORDERS из рис.6-7:
     WHERE  SHIPDATE IS NULL
     ORDER BY ORDERDATE

   Здесь фраза WHERE возвращает в качестве результата только заказы,для ко-
торых значение в столбце SHIPDATE является пустым (null); т.е.только заказы,
которые еще не выполнены.Фраза ORDER BY располагает их в хронологическом по-
рядке таким образом,что первыми отображаются наиболее "старые" заказы.
   Обратите внимание,что вводимое здесь условие упорядочения является просто
условием по умолчанию или базовым для любоых условий выбора,которые устанав-
ливает оператор.Например,если оператор указывает некоторый CLIENTID (иденти-
фикатор клиента),SQL*Forms возвратит в качестве результата для этого клиента
все невыполненные заказы в их хронологическом порядке.
   Так как WHERE и ORDER BY являются стандартными конструкциями SQL,при на-
писании этих фраз вы должны следовать правилам из "SQL*Plus.Руководство по-
льзователя".Можно использовать каждую из фраз в отдельности или обе одновре-
менно,но в последнем из указанных случаев фраза WHERE должна стоять первой.
Имеется одно исключение из стандарта для синтаксиса SQL: если используется
только фраза ORDER BY,при желании ключевое слово ORDER BY можно опустить.
   Ниже приведены некоторые примеры условий упорядочения:
    NAME

в блоке CLIENTS располагает записи в алфавитном порядке имен клиентов;
    WHERE  COMPLAN = 'A'
    AND   ORDERDATE SYSDATE - 365

в блоке ORDERS выбирает только заказы,помещенные за последний год в план за-
казов А;
             WHERE  ORDERID = : ORDERS.ORDERID
             ORDER BY  ITEMNO

в блоке LINEITEMS выбирает только строки,которые соответствуют ORDERID (иде-
нт.заказа) блока ORDERS и упорядочивает их по значению ITEMNO (номеров эле-
ментов).
Примечание: расстановка записей,упорядоченных по значению поля типа CHAR,за-
            висит от схемы упорядочения вашей системы (см.EПриложение DF).

   Для дополнительных примеров и более полного объяснения фраз ORDER BY и
WHERE см."SQL*Plus.Руководство пользователя".
   В окне SPECIFY DEFAULT ORDERING имеется три действия:
 * использовать для "прокрутки" вверх или вниз FORWARD и BACKWARD соответст-
   венно,если условие упорядочения по размеру больше,чем может может вмести-
   ть окно
 * использовать DELETE для стирания содержимого всей области ввода,отменяя
   таким образом условие упорядочения.Когда вы удовлетворены состоянием
   WHERE и ORDER BY,нажмите [Accept] для сохранения изменений и возврата к
   окну DEFINE BLOCK.В противном случае,чтобы аннулировать внесенные вами
   изменения,нажмите [Exit/Cancel].

                      EОкно SPECIFY BLOCK OPTIONSF
   После выбора OPTIONS в окне DEFINE BLOCK вы увидите окно SPECIFY BLOCK
OPTIONS.Вы можете использовать это окно для регулирования спосба отображе-
ния,проверки данных и буферизации записей,и для включения блока в меню бло-
ка.
                  Вы можете управлять следующими опциями:
 1.Check for unique Key (проверка для уникального ключа):
    Если вы выбрали эту опцию,SQL*Forms будет подразумевать,что любая запи-
    сь,внесенная в блок или измененная в блоке,имеет уникальное множество
    значений в полях,определенных в его первичном ключе (вы можете исполь-
    зовать окно SPECIFY ATTRIBUTES,описанное в главе 7,чтобы внести поля в
    ключ и определить, можно ли их изменять).
        Эта опция используется для обеспечения гарантии,что каждая запись,
    внесенная или измененная с помощью формы,имеет уникальный идентификатор,
    который не дублирует строки,уже имеющиеся в таблице.Тем не менее,созда-
    ние в таблице индекса типа UNIQUE является гораздо более эффективным
    средством для достижения того же самого результата,и обеспечивает уника-
    льность для всех записей в таблице,не обязательно внесенных или изменен-
    ных посредством этой формы.Кроме того,вы можете иметь несколько уникаль-
    ных индексов, но только один первичный ключ.
 2.Display in block menu (отобразить в меню блока): Если выбирается эта оп-
    ция (умолчание),то в меню блока при нажатии оператором [Menu] в окне
    DEFINE BLOCK будет появляться описание блока.Вы можете скрыть этот блок
    с помощью исключения данной опции.
 3.Number of rows displayed (количество отображаемых строк): В этой области
    ввода указывается количество одновременно отображаемых строк.Вы можете
    создать моноблок (с одной строкой - по умолчанию) или мультиблок (с бо-
    лее,чем одной строкой).Если это блок по умолчанию,данный выбор уже сде-
    лан,но здесь вы можете его изменить.
        Мультиблок должен умещаться на одной странице.Если не существует ме-
    ста,достаточного для размещения записей на одной странице,можно задать
    меньшее число записей или расположить блок на другой странице.
 4.Number of rows buffered (количество буферизованных строк): В этой области
    ввода указывается,сколько записей будут одновременно храниться в основ-
    ной памяти компьютера.
        SQL*Forms резервирует пространство,достаточное для буферизации как
    минимум 300 строк для всех блоков формы.Блоки форм конкурируют за это
    буферное пространство; строки,которые не помещаются в буфере,сохраняются
    на диске,что увеличивает время доступа к ним.По крайней мере,значение в
    этой области гарантирует пространство для указанного количества записей
    в буфере этого блока.Однако,если общее число строк,буферизованных для
    всех блоков,в итоге больше 300,для хранения дополнительных записей будет
    необходима дополнительная память.
        По умолчанию значение для этой области ввода такое же,как и число
    записей,отображаемое в блоке.
 5.Number of lines per row (количество строк на запись): В данной области
    ввода указывается,сколько строк экрана отводится для размещения каждой
    записи мультиблока.Если блок содержит полей больше,чем может разместить-
    ся в одной строке,вы можете использовать эту опцию для того,чтобы "раз-
    нести" их на 2 или более строки (см.рис.6-9).Если вы указываете строк
    больше,чем поля фактически занимают,SQL*Forms будет оставлять пустые ст-
    роки между записями.
           Когда вы удовлетворены указанными для блока опциями,нажмите
[Accept] для сохранения изменений и возврата к окну DEFINE  BLOCK.Чтобы ан-
нулировать внесенные вами изменения,нажмите [Exit/Cancel].

                     EТриггеры уровня блокаF
     Триггер является набором команд,которые приводятся в действие при нас-
туплении некоторого события во время выполнения формы.Вы можете использовать
TRIGGER в окне DEFAULT BLOCK для определения триггеров уровня блока,которые
будут выполняться,когда оператор вводит блок,выполняет запрос,передвигается
от записи к записи,вносит изменения или покидает блок.Например,можно опреде-
лить триггер для того,чтобы:
 * гарантировать,что N заказчика в записи заказа определен в таблице заказ-
   чиков
 * гарантировать,что значение в поле сниженной цены не превышает значения в
   поле цены по реестру
 * назначить новому заказу уникальный,следующий по порядку N
 * обновить дату последней модификации столбца таблицы
 * скорректировать N служащего в таблице предполагаемого распределения долж-
   ностей персонала,когда он изменяется в таблице служащих
 * запретить клавишу [Delete Record] для какого-либо блока.
     Для получения дополнительной информации об определении этих и других
триггеров уровня блока см.главу 8.

+                                EГЛАВАF E7F
                      EСоздание и Определение ПолейF
     Информация из таблиц БД появляется в полях формы во время ее функциони-
рования.Каждое поле представляет собой как бы окошечко для одного столбца БД
или для какой-либо другой информации,например,результата вычислений над дру-
гими полями.Эта глава описывает 3 вида полей и объясняет как:
 * создать поле
 * определить его тип данных
 * выбрать его атрибуты
 * проверить его данные
 * определить другие характеристики поля

                                EВиды полейF
     Существует 3 вида полей,которые вы можете создать в блоке.
     EПоле базовой таблицыF соответствует столбцу базовой таблицы блока.
Используя такое поле,оператор может запрашивать,редактировать,вставлять и
удалять данные в столбце таблицы (разумеется,в тех рамках,которые вы,как ра-
зработчик формы,установили).
          В примере в блоке ORDERS к таким полям относятся поля ORDERID
(идентификатор заказа) и ORDERDATE (дата заказа).
      EПоле для просмотра таблицыF соответствует столбцу из таблицы,не яв-
ляющейся базовой для текущего блока.Для чтения данных из таблицы в такое по-
ле таблицы можно использовать триггер.Однако,из данного блока оператор не
может запрашивать,корректировать,вставлять и удалять данные в столбцах таб-
лицы.Все это можно делать из поля того блока,для которого таблица является
базовой.
          Обычно поля для просмотра используются для отображения связанной
информации в форме.В блоке ORDERS таким полем является NAME,в нем отображае-
тся информация из таблицы CLIENT при введении идентификатора клиента
(CLIENTID).Заметьте,что NAME является полем базой таблицы в блоке CLIENT.
     EПоле для временной информацииF не соответствует какому-либо опреде-
ленному столбцу таблицы.Вы можете применить триггер для вычисления и отобра-
жения информации в таком поле,используя значение из таблиц,других полей фор-
мы и значения операторского ввода.
           Обычно поля для временной информации используются для вычислений,
для высвечивания сообщений или вариантов выбора.В блоке ORDERS таким полем
является CHECKTOTAL,в нем отображается информация,вычисленная по значениям
полей блока LINEITEMS.

                               EСоздание поляF
     Новые поля в блоке создаются в экранном построителе.Вы попадете в него
автоматически после выбера опции CREATE для создания блока пользователя в
окне CHOOSE FORM.
     Когда вы создаете блок по умолчанию,SQL*Forms автоматически создаст по-
ля для выбранных вами столбцов.Если вы захотите добавить поля,то выберите
опцию MODIFY в окне CHOOSE BLOCK для входа в экранный построитель.Не забыва-
йте правильно вводить в окне нужные вам имя блока и N страницы.
     Находясь в экранном построителе,для создания нового поля проделайте
следующие операции:
 1.Поместите курсор в то место,где должно начинаться поле,и нажмите [Select].
 2.Переместите курсор туда,где должно заканчиваться поле,и снова нажмите
   [Select].
 3.Нажмите [Create Field].SQL*Forms создаст поле и высветит окно DEFINE
   FIELD,в котором вы можете определить параметры поля.
     При создании мультиблока поля создаются только для первой записи,для
остальных записей необходимо оставить достаточно свободного места на страни-
це.Вы можете использовать окно SPECIFY BLOCK OPTIONS,описанное в главе 6,для
задания числа записей в блоке и числа строк экрана для каждой записи.
     Для создания нового поля на другой странице формы нажмите [Accept] для
возврата в окно CHOOSE BLOCK.Наберите N страницы в поле ввода и выберите оп-
цию MODIFY для повторного входа в экранный построитель.
     Таким же образом можно размещать поля на нулевой странице формы.Поско-
льку оператор не сможет высветить эту страницу,то сюда можно поместить про-
межуточные значения и конфиденциальную информацию.

                         EОпределение поляF
     Определить поле означает задать его параметры,указывающие,например,:
 * какому столбцу таблицы оно соответствует(если такое соответствие имеется)
 * тип данных
 * будет ли оно высвечиваться; если да,то каким образом
 * как оператор попадает в него
 * какие проверки установлены для него
 * какие триггеры оно включает.
     Когда вы создаете поле (либо SQL*Forms создает его за вас в блоке по
умолчанию) этим параметрам присваиваются значения по умолчанию.Для изменения
этих значений вы можете использовать опции в окне DEFINE FIELD.
     Окна,используемые при определении поля,показаны на рисунке 7-1.

            Ъ------------------------ї
            і ЭКРАННЫЙ ПОСТРОИТЕЛЬ   і
            А--------В--------------ДЩ
              [Create Field] і      ^
               или [Select]  і      і
                + [Define]   і      і
                             і      і
                             і      і[Accept]
                ATTRIBUTES   v      і
                       Ъ----ДБ------Б------Дї
         Ъ------------Дґ    ОКНО            і<------------Дї
         і             і                    і TRIGGER      і
         і     Ъ------>і  DEFINE FIELD      Г--------ї     і
         і     і       А----ДВ--------------Щ        і     і
         і     і VALIDATION  і      ^                і     і
         і     і             і      і                і     і
         v     і[Accept]     v      і[Accept]        v     і[Accept]
      Ъ--Б----ДБ--Дї      Ъ--Б------Б--ї       Ъ----ДБ----ДБ----ї
      і  ОКНО      і      і  ОКНО      і       і   ОКНО         і
      і SPECIFY    і      і SPECIFY    і       і CHOOSE TRIGGER і
      і FNNRIBUTES і      і VALIDATION і       і  (см.главу 8)  і
      А------------Щ      А------------Щ       А----------------Щ
            Рис.7-1.Определение поля

                           EОкно DEFINE FIELDF
     Для определения параметров поля используется окно DEFINE FIELD.Оно поя-
вляется автоматически,когда вы создаете новое поле.
     Чтобы высветить окно DEFINE FIELD для определения существующего поля,
включая также поля,созданные автоматически в блоке по умолчанию,войдите в
экранный построитель с нужным вам блоком.Затем поместите курсор в любом мес-
те поля и нажмите [Define].
     Чтобы определить поле,необходимо задать его параметры.
 1.Seg# (порядковый N).В этой области ввода наберите порядковый N,в соответ-
   ствии с которым происходит перемещение курсора к этому полю при нажатии
   оператором клавиши [Next Field] или [Previos Field].Для дополнительной
   информации см."Изменение порядка следования" в главе 4.
 2.Name (Имя).В этой области ввода наберите имя столбца таблицы,соответству-
   ющего данному полю.Столбец д.б. столбцом базовой таблицы блока.Если поле
   не соответствует ни какому столбцу БД (включая поля управляющего блока),
   то можно использовать любое разрешенное имя.
       Если вы не уверены,какой столбец выбрать,выберите опцию COLUMNS для
       высвечивания окна LIST COLUMNS,содержащего перечень столбцов таблицы.
              Если вы используете эту область ввода для переименования поля,
       помните,что триггеры,связанные с этим полем,автоматически не изменяю-
       тся.Вам придется самим найти и изменить эти триггеры.
 3.Data Type (Тип данных).Из списка типов полей SQL*Forms выберите нужный
   тип,который определяет,какие символы можно вводить в поле и как они будут
   форматироваться.Более подробное объяснение см.в следующем разделе "Типы
   полей SQL*Forms".
 4.Этот пункт необязателен.Чтобы определить триггеры для поля,выберите TRIG-
   GER для высвечивания окна DEFINE TRIGGER.Триггеры уровня поля описываются
   далее в этой главе.
 5.Этот пункт необязателен.Для выбора характеристик поля выберите опцию
   ATTRIBUTES для высвечивания окна SPECIFY ATTRIBUTES,описанного далее в
   этой главе.
 6.Этот пункт необязателен.Для управления проверкой данных поля,выберите оп-
   цию VALIDATION для высвечивания окна SPECIFY VALIDATION,описанного далее
   в этой главе.Когда вы будете удовлетворены установленным вами определени-
   ем поля,нажмите [Accept] для сохранения изменений и вернитесь в экранный
   построитель.Если вы,наоборот,хотите отменить произведенные изменения,то
   нажмите [Exit/Cancel].

                           EТипы полей SQL*FormsF
     Поскольку типов полей SQL*Forms гораздо больше,чем типов данных ORACLE,
то вам представляется большая свобода в выборе способа отображения информа-
ции.Имеется 12 типов полей:
 * Поля типа CHAR (символьные) могут содержать любое сочетание высвечиваемых
   символов,включая буквы,цифры,пробелы,знаки пунктуации и специальные сим-
   волы.
 * Поля типа ALFA (буквенные) могут содержать любые сочетания букв,как про-
   писных,так и строчных.
 * Поля типа TIME(времени) могут содержать время суток в формате HH24:MM:SS,
   например: 09:15:30
             15:35:45
          Поля типа TIME могут применяться только в SQL*Forms.В действитель-
          ности они обращаются к столбцам БД типа NUMBER (числовые),а не к
          столбцам типа DATE,и вне SQL*Forms довольно сложно преобразовать
          хранящиеся значения в формат времени.Если хотите,вы можете исполь-
          зовать функцию TO_CHAR в триггере для выделения из столбца типа
          DATE информации о времени.
 * Поля типа NUMBER (числовые) могут содержать любые числа,со знаком или
   без,с 10-ной точкой и без нее,в обычной или экспоненциальной форме.
   Например: 10963
            -15
            0.01
            1018.996
            1.85Е3
          Имейте в виду,что в SQL*Forms нельзя использовать запятую в качес-
          тве разделителя в числах,хотя другие продукты ORACLE могут приме-
          нять их при высвечивании или печати чисел.
 * Поля типа INT (целые) могут содержать целые числа-числа без 10-ной точки.
 * Поля типа MONEY (денежные) могут содержать числа,представляющие денежные
   суммы.По стандарту Соединенных Штатов - это числа в следующих формах:
          10.95
          0.99
          10000.00
          -15.47
 * Поля типа RNUMBER,RINT и RMONEY аналогичны типам NUMBER,INT и MONEY за
   тем исключением,что значения в полях выравнены вправо,а не влево.Напри-
   мер,вышеприведенные данные для типа MONEY будут выглядеть в полях типа
   RMONEY следующим образом: 10.95
                              0.99
                          10000.00
                            -15.47
 * Поля типа DATE (дата) могут содержать дату в формате DD-MON-YY,например:
            22-MAY-1986
            09-DEC-1986
 * Поля типа JDATE (дата по Юлианскому календарю) могут содержать дату в фо-
   рмате MM/DD/YY,например: 05/22/86
                            12/09/86
 * Поля типа EDATE (дата в Европейской форме) могут содержать дату в формате
   DD/MM/YY,например: 22/05/86
                      09/12/86
     Типы полей JDATE и EDATE можно применять только в SQL*Forms.В действи-
тельности они обращаются к столбцам типа NUMBER БД,а не к столбцам типа
DATE,и вне SQL*Forms не существует простого способа для преобразования хра-
нящихся значений в формат даты.Если хотите,то вы можете использовать функцию
TO_CHAR в триггере для отображения столбца типа DATE в формате ином,нежели
DD-MON-YY.

                        EОкно SPECIFY ATTRIBUTESF
     Если вы выбираете опцию ATTRIBUTES в окне DEFINE FIELD,то увидите окно
SPECIFY ATTRIBUTES.В нем вы можете выбрать или исключить 13 пунктов,являющи-
хся характеристиками поля.По умолчанию выбраны пункты: "Database Field",
"Displayed","Input allowed","Query allowed","Update allowed",а также "Manda-
tory" только для полей,соответствующих столбцам,объявленным как NOT NULL.
     Некоторые атрибуты логически связаны между собой.Некоторые нельзя выб-
рать,не выбрав вначале другие,при исключении других некоторые могут автома-
тически выбираться или исключаться.Например,нельзя определить поле как
"Input allowed",если оно еще не определено как "Displayed",соответственно
при исключении "Displayed" автоматически отменяется "Input allowed".Эта вза-
имосвязь поясняется при обсуждении каждого атрибута и показана в таблице 7-1.
     Закончив определение атрибутов для поля,нажмите [Accept] для возврата в
окно DEFINE FIELD.

                            EАтрибуты поляF
     Каждое поле в форме имеет набор атрибутов и характеристик,которые можно
выбрать в окне SPECIFY ATTRIBUTES.

                    Атрибут "Database Field" (поле БД)
     Такое поле представляет столбец базовой таблице для блока формы.Значе-
ния таких полей всегда считываются,либо записываются в соответствующих стол-
бцах базовой таблицы.
     Вы можете использовать другие поля (не поля БД) для вычисления значе-
ний,для временного хранения информации,вывода связанной информации из других
таблиц.Хотя они непосредственно не связаны ни с какими столбцами таблицы,вы
можете определить триггеры для считывания,либо для вычислений с использова-
нием значений столбцов таблицы (либо для хранения и вычисления).
     Атрибуты "Primary Key" (первичный ключ) Первичный ключ - это поле или
группа полей,которые служат в качестве уникального идентификатора записи.
Чтобы включить поле в первичный ключ,выберите этот атрибут.Затем выберите
опцию "Check for unique Key" в окне SPECIFY BLOCK OPTIONS (см.главу 6),чтобы
сообщить SQL*Forms,что вставляемые и редактируемые записи не дублируют зна-
чения ключей других записей.
     Первичный ключ используется для обеспечения уникальности записей в фор-
ме.Например,чтобы установить,что ни одна запись,вставляемая или редактируе-
мая в форме с информацией о служащих,не имеет идентификатор служащего,такой
же,как другая запись формы или строка таблицы,выберите "Primary Key" для по-
ля идентификатора служащего.Не забудьте,что этот атрибут будет недействите-
лен до тех пор,пока вы также не выберете "Check for unique Key".
     Имейте в виду,что уникальность устанавливается для всех полей,входящих
в первичный ключ.Другими словами,уникальность нарушается тогда,когда каждое
входящее в первичный ключ поле какой-либо записи имеет такое же значение,что
и соответствующее поле или столбец другой записи или строки.
     Для установки уникальности обычно более эффективным является создание в
таблице индекса типа UNIQUE,поскольку он распространяется на все строки таб-
лицы,а не только на вставляемые и редактируемые в форме.Кроме того,можно
иметь несколько индексов типа UNIQUE и только один первичный ключ.
     Поле с атрибутом "Primary Key" м.б. также полем БД.

                  Атрибут "Displayed" (отображаемое поле)
Во время выполнения формы высвечиваются только поля с атрибутом "Displayed".
Вы можете исключить этот атрибут,чтобы скрыть от оператора вычисления или
копируемые значения.Не применяйте неотображаемые поля,чтобы скрыть конфиден-
циальную или защищенную информацию,поскольку в случае ошибкок значение поля
м.б. высвечено при нажатии оператором [Display Error].Поэтому,лучше помещать
неотображаемые поля на нулевую страницу формы,где они будут недоступны.
    Для удобства,при разработке формы неотображаемые поля остаются видимыми.
     Чтобы высветить поле,но скрыть его значение,используйте атрибут "No
echo",описанный ниже в этой главе.

                 Атрибут "Input allowed" (ввод разрешен)
     Только в том случае,если поле имеет атрибут "Input allowed",оператор
может помещать курсор в это поле для ввода или изменения его значения (не в
режиме запроса).Если хотите,вы можете исключить этот атрибут,например,чтобы
защитить вычисляемые значения от изменения.
     Поле с этим атрибутом должно также иметь атрибут "Displayed".

                 Атрибут "Query allowed" (запрос разрешен)
     Только в том случае,если поле имеет атрибут "Query allowed",оператор
может войти в него для ввода условий выбора (в режиме запроса).Можно исклю-
чить этот атрибут для предотвращения выбора записей,связанных со значением в
соответствующем столбце БД.
     Поле с этим атрибутом также должно иметь атрибут "Displayed".

            Атрибуты "Update allowed" (корректировка разрешена)  и
               "Update If NULL" (корректировка,если пусто)
     Эти связанные атрибуты являются взаимоисключающими.Вы не можете выбрать
одновременно оба атрибута для поля; можно выбрать либо один,либо ни одного.
     Если выбрано "Update allowed",то оператор может изменять значение поля
в записях,полученных в результате запроса.
     Если выбрано "Update If NULL",то оператор может изменять значение поля
в записях,полученных в результате запроса,только в том случае,если значение
поля пусто (пустое значение).
     Если поле не имеет ни одного из обсуждаемых атрибутов,оператор не может
изменять его значение в выбираемых записях ни при каких условиях.
     Поле с этими атрибутами должно также иметь атрибуты "Displayed" и
"Input allowed".

                Атрибут "Fixed Length" (фиксированная длина)
  Значение,вводимое в поле с этим атрибутом,должно иметь длину такую же,как
и длина поля.Вы можете выбрать этот атрибут для полей,содержащих какие-либо
коды,либо другую информацию,для которой неприемлемы укороченные значения.
     Этот атрибут часто используется вместе с атрибутом "Autoskip",описанным
ниже в этом разделе.
     Поле с фиксированной длиной также должно иметь атрибуты "Displayed" и
"Input allowed".

                Атрибуты "Mandatory" (обязательно значение)
     Значение поля с таким атрибутом не м.б. пустым.Можно выбрать этот атри-
бут,например,для полей,содержащих число - идентификатор заказа,- которое
м.б. обязательно введено.
     Обратите внимание,что атрибуты "Mandatory"  и "Fixed Length" независимы
друг от друга.Если поле имеет атрибут "Fixed Leugth",но не имеет "Mandato-
ry",то его значение м.б. пустым,если же значение не пусто,то оно должно име-
ть такую же длину,как и поле.Поле с атрибутом "Mandatory" должно также иметь
атрибуты "Disolayed" и "Input allowed".

                  Атрибуты "Uppercase" (прописные буквы)
     Если поле имеет этот атрибут,то при вводе строчных букв они преобразую-
тся в прописные.Этот атрибут можно выбрать,чтобы помочь оператору вводить
значения в правильном формате.
     Имейте ввиду,что этот атрибут влияет только на значения,введенные в по-
ле посредством данной формы.Строчные буквы м.б. введены в соответствующие
столбцы таблицы посредством другой формы,либо какой-либо иной программой,не-
жели SQL*Forms.
     Поле с атрибутом "Uppercase" также должно иметь атрибуты "Displayed" и
"Input allowed".Этот атрибут действителен только для полей типа CHAR и ALPHA.

               Атрибут "Autoskip" (автоматический переход)
     Если поле имеет атрибут "Autoskip",то SQL*Forms автоматически перемеща-
ется к следующему полю при вводе символа в последнюю позицию поля.В против-
ном случае,для перемещения оператору необходимо нажать [Next Field],даже ес-
ли поле заполнено.
     Этот атрибут особенно полезен для полей с атрибутом "Fixed Length".Если
поле не имеет атрибут "Fixed Length",то оператор может перейти к следующему
полю,не доходя до последней позиции,а просто нажав [Next Field].
     Поле с атрибутом "Autoskip" должно также иметь атрибуты "Displayed" и
"Input allowed".

              Атрибут "Automatic Help" (автоматическая помощь)
     Если поле имеет этот атрибут,то подсказка для поля будет высвечиваться
каждый раз,когда курсор находится в поле (кроме случаев,когда высвечивается
сообщение об ошибке).Разумеется,для того,чтобы атрибут работал должным обра-
зом,вам необходимо определить подсказку (помощь) в окне SPECIFY VALIDATION,
описанном ниже.
     Поле с  этим атрибутом должно также иметь атрибуты "Displayed" и "Input
allowed".

                      Атрибут "No echo" (без эха)
     Если поле имеет атрибут "No еcho",то его значение всегда отображается
как пробелы,даже если само поле высвечивается.Можно выбрать этот атрибут,
чтобы скрыть пароль,либо другую секретную информацию.Если в поле с атрибутом
"No echo" произойдет серьезная ошибка,то значение м.б. высвечено,когда опе-
ратор нажмет [Display Error].Чтобы действительно защитить значение,поместите
поле на нулевую страницу формы,объявив его при этом "No echo".
     Поле с этим атрибутом должно также иметь атрибут "Displayed".

                             ТАБЛИЦА 7-1
           Атрибуты по умолчанию и взаимосвязь атрибутов.
     __________________________________________________________
     іПеред выбором ниже- і ...вы должны сначала выбрать      і
     іследующего атрибута і   следующий атрибут.              і
     і                    і___________________________________і
     і                    і Databaseі DisplayedіInput Allowed і
     і____________________і_________і__________і______________і
     іDatabace Field (D)  і         і          і              і
     іPrimary Key         і     *   і          і              і
     іDisplayed (D)       і         і          і              і
     іInput Allowed (D)   і         і    *     і              і
     іQuery Allowed (D)   і         і    *     і              і
     іUpdate Allowed (D)  і         і    *     і       *      і
     іUpdate if NULL      і         і    *     і       *      і
     іFixed Length        і         і    *     і       *      і
     іMandatory           і         і    *     і       *      і
     іUppercase           і         і    *     і       *      і
     іAutoskip            і         і    *     і       *      і
     іAutomatic Help      і         і    *     і       *      і
     іNo Echo             і         і    *     і              і

 (D) - Атрибут выбирается по умолчанию.
  *  - Атрибут слева автоматически исключается,если исключается атрибут све-
       рху .

                           EОкно SPECIFY VALIDATIONF
   Если вы сделали выбор VALIDATION в окне DEFINE FIELD,то увидите окно SPE-
CIFY VALIDATION.В нем находится 7 областей ввода,которые помогут вам устано-
вить систему подсказок и проверок для значений,вводимых оператором в поле.
     (Для проверки вводимых значений также можно использовать триггеры поля,
тип данных и атрибуты,проверяющие вводимые значения.См.раздел "Проверка дан-
ных поля" ниже в этой главе,где описываются эти методы).
     Для установки проверки значений поля можно использовать любое число
элементов окна SPECIFY VALIDATION.3 области ввода имеют значения по умолча-
нию,но,при желании,вы можете изменить эти значения.
 1.Field Length(длина поля).В этой области ввода наберите максимальное число
   знаков,которые можно ввести в данное поле.Для полей БД это число не долж-
   но превышать ширину столбца таблицы.
            По умолчанию длина поля совпадает с шириной вывода,(количество
   символов,размещаемых в поле на экране).Если вы устаналиваете длину поля
   большей,чем ширина вывода,оператор может использовать [Left]/[Right] или
   [Scroll Left]/[Scroll Right] для горизонтальной "прокрутки" поля.Имейте в
   виду,что горизонтальное перемещение м.б. некорректно,если поле выровнено
   по правой границе (например,RNUMBER,RINT или RMONEY).
            SQL*Forms будет игнорировать тот факт,что поля короче,чем ширина
   вывода.
 2.Query Length (длина запроса): В этой области ввода наберите максимальное
   число символов,которое можно вводить в поле в качестве условия запроса.
            По умолчанию длина запроса равняется длине поля.Если вы устано-
   вите длину запроса большую,чем ширина вывода поля,то оператор может испо-
   льзовать [Left] и [Right] либо [Scroll Left] и [Scroll Right] для горизо-
   нтального перемещения в поле.Это может пригодиться при вводе сложных ус-
   ловий запроса в форме,в которой пространство ограничено.
            SQL*Forms проигнорирует тот факт,что длина запроса короче,чем
   длина поля.
 3.Copy Field Value from (копировать значение поля из).В этой области ввода
   укажите блок и поле,из которых будет скопировано значение.
            Предположим,вы хотите,чтобы все записи во вспомогательном блоке
   (например,LINEITEMS) соответствовали текущей записи в основном блоке (на-
   пример,ORDERS).Для этого вам необходимо скопировать ORDERID из блока OR-
   DERS в блок LINEITEMS.Таким образом,будет гарантировано,что любые новые
   элементы строк,добавляемые к текущему заказу,будут иметь правильный ORDE-
   RID и,что запросы по элементам LINETIEMS (позициям) будут считывать запи-
   си только текущего заказа.
 4.Default (по умолчанию).В этой области ввода наберите значение,которое бу-
   дет появляться по умолчанию в данном поле для новых записей.Если вы уста-
   новили "Input allowed",то оператор сможет изменить это значение.
            Значение по умолчанию м.б. значением системной переменной (нап-
   ример,$$DATE$$ или $$TIME$$ для текущей даты или времени),либо значением
   другого поля (например,:ORDERS.ORDERID).
 5.Range (интервал).В этой области ввода,если хотите,укажите величину наиме-
   ньшего и наибольшего значения переменной для поля.SQL*Forms не позволит
   оператору вводить или редактировать значения,не входящие в этот интервал.
   Числовые значения проверяются в числовом порядке,значения даты - в хроно-
   логическом порядке,алфавитно-цифровые символы - в соответствии со схемой
   упорядочения символов вашей системы.
 6.List of Values (список значений).В этой области ввода укажите таблицу и
   столбец,содержащий список возможных значений для поля.Для высвечивания
   этих значений оператор может нажать [List Field Values],значения будут
   высвечиваться по одному,по возрастанию.Если такой список определен,то ин-
   тервал (если он задан) игнорируется (см.главу 5).
             Обратите внимание,что список значений предоставляет возможные,
   но не обязательные значения.Ничего не случится,если оператор введет зна-
   чение,не входящее в этот список.Для установки проверки на вхождение в
   список вы можете использовать триггер (см.главу 8).
 7.Help (помощь).В этой области ввода наберите текст сообщения,которое будет
   высвечиваться при нажатии оператором [Help] во время работы с этим полем.
   По умолчанию сообщение выглядит следующим образом: "Enter Value for: имя
   поля" (введите значение для ...).
               Если вы хотите,чтобы сообщение автоматически высвечивалось
   каждый раз при входе в поле,можно использовать атрибут "Automatic help".
               Когда вы установили все критерии проверки для поля,нажмите
   [Accept] для возврата в окно DEFINE FIELD.

                         EТриггеры уровня поляF
     Триггер представляет собой набор команд,которые выполняются при наступ-
лении определенного события во время выполнения формы.Можно использовать де-
йствие TRIGGER в окне DEFINE FIELD для определения триггеров уровня поля,ко-
торые будут выполняться,когда оператор входит,редактирует или покидает поле.
Например,вы можете определить триггеры,чтобы производить следующие действия:
 * проверять вводимые данные по значениям столбца таблицы
 * считывать наименование товара и объявленную цену из таблицы при вводе
   оператором цифрового кода товара
 * рассчитывать общий итог по заказу согласно полям количества и цены
 * проверять,чтобы действительная цена была не более,чем на 20% меньше объя-
   вленной цены
 * переходить к другому блоку при нажатии оператором [Next Field].
         Для получения подробной информации об определении этих (а также и
   других) триггеров уровня поля см.главы 8 и 9.

                        EПроверка данных поляF
     Как вы уже видели,существует несколько способов проверки вводимых опе-
ратором значений :
 * Указание типа поля в окне DEFINE FIELD (заданный тип поля не позволит
   оператору ввести не разрешенные символы,например,цифры в поля типа ALFA
   или буквы - в поля NUMBER)
 * Выбор атрибутов поля в окне SPECIFY ATTRIBUTES таких,как:
   * E"Update allowed"F и E"Update if NULL"F для предотвращения измене-
      ния существующих значений.
   * E"Fixed Length"F для исключения частичного (не полного) заполнения
      поля непустыми значениями
   * E"Mandatory"F для исключения пустых значений.
   * Установка  проверок  значений в окне SPECIFY VALIDATION,таких,как:
   * E"Field lenth"F для исключения слишком длинных значений.
   * E"Range"F для исключения значений,которые не попадают в установленный
      интервал.
   * Триггеры уровня поля в окне CHOOSE TRIGGER (см.главу 8-9) м.б. исполь-
     зованы для многих видов проверки.Если триггер для поля завершается неу-
     дачно,само поле считается некорректным.

                  EКак и Когда проверяются данные полей"F
     Проверки Update allowed,Update if NULL,Field length производятся во
время ввода с клавиатуры.Так,например,SQL*Forms не позволит оператору ввести
значение длиннее положенного,или ввести значение в поле,в котором не разре-
шено редактировать.
     Остальные проверки для поля выполняются в следующих точках процесса
проверки данных:
 * когда оператор (или триггер) перемещает курсор за пределы поля,проверяет-
   ся,изменилось ли его значение
 * когда оператор (или триггер) перемещает курсор за пределы записи,проверя-
   ются все измененные поля записи
 * когда оператор (или триггер) перемещает курсор за пределы блока,проверяю-
   тся все измененные поля текущей записи блока
 * когда оператор(или триггер) записывает изменения,проверяются все изменен-
   ные поля всех записей всех блоков,за исключением управляющих блоков.
     Когда достигается какая-либо из точек проверки,SQL*Forms вначале прове-
ряет,изменялось ли значение поля.Только в том случае,если оно изменялось,
производится действительная проверка данных в такой последовательности: сна-
чала - по типу поля,атрибутам,по заданной проверке значений,а затем посредс-
твом выполнения триггеров.
     Если проверка данных поля завершилась неудачно для какого-либо поля ка-
кой-либо записи,то весь процесс сохранения изменений прекращается и все из-
менения в БД отменяются.Оператор должен исправить некорректное значение и
снова произвести сохранение изменений.
     Поскольку этапы проверки выполняются в определенной последовательности,
то триггеры,изменяющие значения не текущих полей (т.е.полей в стороне от ку-
рсора),могут приводить к нежелательным побочным эффектам.Если вы используете
такие триггеры,смотрите главу 8 для более подробного обсуждения данного воп-
роса.

+                           EГЛАВАF E8F
                              EТриггерыF
     Триггер - это набор команд,который выполняется или запускается при нас-
туплении некоторого события во время выполнения формы.Вы можете использовать
триггеры для того,чтобы выполнить проверку,выдать подсказку или дополнить
то,что оператор вводит в форму.
     Триггеры подробно рассматриваются в 2 главах этой книги.
     Эта глава описывает :
 * терминологию триггеров
 * виды команд триггера
 * уровень,область действия и контекст триггера
 * типы триггеров
 * как определить триггер
 * как триггеры выполняются
 * результаты работы триггеров.
     Глава 9 "Синтаксис триггеров",в свою очередь,содержит подробную инфор-
мацию о командах SQL и SQL*Forms,используемых в триггерах.Там же вы найдете
множество примеров триггеров.
     Триггеры являются основным средством повышения возможностей SQL*Forms -
но,вместе с тем,усложняют работу с ним.Хотя написание триггеров внешне не
похоже на традиционное программирование,оно также м.б. достаточно сложным.Мы
рекомендуем основательно изучить язык SQL и/или традиционный язык программи-
рования до того,как взяться за эту главу.

                             EО триггерахF
     Триггер - это набор команд,выполнение которых начинается при наступле-
нии определенного события во время выполнения формы.Каждый триггер может со-
стоять из одного или более шагов,каждый из которых содержит одну команду.

                           EКоманды триггераF
     Существует 3 вида команд,которые вы можете использовать в триггерах.Вы
можете соединять эти виды команд в одном триггере,но не в одном шаге.
 * Команды SQL обрабатывают информацию из таблицы БД (или формы).Триггер мо-
   жет запрашивать или модифицировать любую таблицу,к которой оператор имеет
   соответствующие права доступа.Расширенный синтаксис SQL позволяет тригге-
   рам передавать значения между таблицами и формами.
                   Например,следующий SQL-триггер автоматически выбирает имя
   клиента из таблицы CLIENT и помещает его в поле формы :
           SELECT NAME
           INTO :ORDERS.NAME
           FROM CLIENT
           WHERE CLIENT.CLIENTID = :ORDERS.CLIENTID
   Ваш триггер может выполнять эту команду каждый раз,когда оператор выбира-
   ет,вводит или изменяет N клиента в форме для заказов.
 * Команды SQL*Forms имитируют действие функциональных клавиш и других опе-
   раций,которые мог бы выполнить оператор.Например,данный макро-триггер пе-
   ремещает курсор в блок LINEITEMS и выполняет запрос :
           #EXEMACRO GOBLK LINEITEMS; EXEQRY;

   Ваш триггер может назначить эту  макрокоманду функциональной клавише та-
   ким образом,что оператор сможет выбрать записи элементов,произведя только
   одно нажатие клавиши.Или,вы можете выполнить этот макрос в любой момент,
   когда оператор выполняет запрос в блоке ORDERS.
 * Подсоединяемые программы вызывают программы пользователя,написанные на
   традиционном языке программирования,таком,как C или COBOL.Подсоединяемые
   программы пользователя могут выполнять вычисления над полями формы,обра-
   щаться к полям таблиц и использовать другие сервисные функции,предостав-
   ляемые ORACLE и SQL*Forms.Команды SQL и SQL*Forms,которые можно использо-
   вать в триггерах,описаны подробно и со множеством примеров в главе 9,"Си-
   нтаксис триггеров", данного руководства.В этой главе также объясняется,
   как вызывать подсоединяемые программы пользователя в триггере.А сами под-
   соединяемые программы пользователя описаны в EПриложении CF.

                        EСобытия триггераF
     Триггеры связаны с пятью типами событий :
 * вход - когда оператор запускает форму на выполнение,или когда курсор вхо-
   дит в новый блок,запись или поле
 * запрос - до или после выборки записей
 * изменение - после изменения оператором значения,или до или после внесения
   в БД результатов транзакции
 * выход - когда оператор покидает форму,либо когда курсор покидает блок,за-
   пись или поле
 * нажатие клавиши - когда оператор нажимает на функциональную клавишу.Имее-
   тся один тип триггеров,которые не запускается каким-либо определенным со-
   бытием :
    * триггеры пользователя - это общие триггеры или подтриггеры,которые ва-
      ми используются многократно или вызываются из других триггеров.
             Вы найдете примеры всех этих типов триггеров в следующей части.

                            EТипы триггеровF
     Определение триггеров начинается в окне CHOOSE TRIGGER,как это описано
в разделе "Определение триггера" далее в этой главе.Однако,тот способ,кото-
рым вы выбираете окно CHOOSE TRIGGER,влияет на уровень,область действия и
тип триггера,который вы желаете определить.

            EУровень,область действия и контекст триггераF
  Уровни триггеров
     Вы можете определить триггеры на 3 уровнях формы :
 * триггеры уровня поля,которые связаны с конкретным полем
 * триггеры уровня блока,которые связаны с конкретным блоком
 * триггеры уровня формы,которые связаны с формой в целом.
     На каждом уровне существуют определенные типы триггеров,которые вы мо-
жете использовать.Они показаны в таблице 8-1 и расположены по типам событий,
которым эти триггеры соответствуют.
     Например,на уровне поля (для некоторого конкретного поля) вы можете
определить триггер pre-field,триггер post-change,триггер post-field,ключевые
триггеры и триггеры пользователя.Исключая триггеры пользователя,тип триггера
является также его именем,которое вы вводите в окне CHOOSE TRIGGER.

                             ТАБЛИЦА 8-1
                 Типы триггеров для каждого уровня
     Ъ--------ДВ----------------------------------------------Дї
     і         і          Уровень                              і
     і Событие Г----------ДВ----------------------ДВ----------Дґ
     і         і           і           Блок        і           і
     і триггераі    Поле   Г----------ДВ----------Дґ  Форма    і
     і         і           і   Запись  і    Блок   і           і
     Г--------ДЕ----------ДЕ----------ДЕ----------ДЕ----------Дґ
     і  Вход   і Pre-Field і Pre-Recordі Pre-Block і Pre-Form  і
     і Запрос  і           і Post-Queryі Pre-Query і           і
     іИзменениеіPost-Changeі EТолько приFі       і           і
     і         і           і EзаписиF  і         і           і
     і         і           і EизмененийF і       і           і
     і         і           і Pre-Deleteі           і           і
     і         і           іPost-Deleteі           і           і
     і         і           і Pre-Insertі           і           і
     і         і           і Pre-Updateі           і           і
     і         і           іPost-Updateі           і           і
     і         і           і           і           і           і
     і  Выход  і Post-FieldіPost-Recordі Post-Blockі Post-Form і
     Г--------ДЕ----------ДБ----------ДБ----------ДБ----------Дґ
     і Нажатие і                    Ключевой                   і
     і клавиши і                                               і
     Г--------ДЕ----------------------------------------------Дґ
     іИдентифи-і        Идентифицированный пользователем       і
     іцированиеі                                               і
     іпользова-і                                               і
     ітелем    і                                               і
     А--------ДБ----------------------------------------------ДЩ
EПримечание:F Каждый тип триггера из данной таблицы м.б. определен на сво-
                ем собственном уровне или правее.

                         Область действия триггера
     Вы можете определить каждый тип триггера как на его собственном уровне,
так и на более высоком уровне.Например,вы можете определить триггер post-
change (уровня поля) на уровне поля,блока или формы.
     Область действия триггера - область,в которой он функционирует - задае-
тся уровнем,на котором этот триггер определен.Таким образом,триггер post-
change,определенный на уровне блока,будет относиться к каждому полю в блоке;
это значит,что он будет выполняться непосредственно после того,как оператор
изменит значение любого поля блока (но не тогда,когда оператор покидает
блок).Триггер post-change,определенный на уровне формы,будет относиться к
каждому полю формы.
     Ъ--------------------------------------------------------Дї
     і                        Форма EMPDEPT                    і
     і  Ъ--------------------------------------------------Дї  і
     і  і                       Блок EMP                    і  і
     і  і      E           F           G            H       і  і
     і  і Ъ--------ДїЪ----------ДїЪ----------ДїЪ----------ї і  і
     і  і іPRE-BLOCKііPOST-UPDATEііPOST-CHANGEііKEY-DELRECі і  і
     і  і А--------ДЩА----------ДЩА----------ДЩА----------Щ і  і
     і  і Ъ----------------їЪ--------------їЪ--------------їі  і
     і  і і  Ъ----------Дї іі              іі              іі  і
     і  і іI іPOST-CHANGEі іі  Ъ--------Дї іі Ъ----------ї іі  і
     і  і і  А----------ДЩ ііK іPRE-FIELDі ііLіKEY-NXTFLDі іі  і
     і  і і  Ъ----------Дї іі  А--------ДЩ іі А----------Щ іі  і
     і  і і JіPOST-FIELD і іі              іі              іі  і
     і  і і  А----------ДЩ іі              іі              іі  і
     і  і А----------------ЩА--------------ЩА--------------Щі  і
     і  А--------------------------------------------------ДЩ  і
     і  Ъ----------ї  Ъ----------ї  Ъ--------ї  Ъ----------ї   і
     і AіPOST-FIELDі BіPRE-INSERTі CіPRE-FORMі DіKEY-DELRECі   і
     і  А----------Щ  А----------Щ  А--------Щ  А----------Щ   і
     А--------------------------------------------------------ДЩ
           Рис.8-1.Область действия триггера

 A  выполняется для всех полей формы,исключая те поля,которые имеют свои со-
    бственные триггеры post-field (например,J).
 B  выполняется для каждого блока формы,за исключением тех блоков,которые
    имеют свои собственные триггеры pre-insert (в этом примере таких нет).
 D  действует для всей формы,исключая те случаи,когда он отменяется тригге-
    ром KEY-DELREC на более низком уровне (например,H).
 G  выполняется для каждого поля блока,за исключением тех полей,которые име-
    ют свои собственные триггеры post-change (например,I).
 H  отменяет триггер D только для данного блока.
 I  отменяет триггер G только для данного поля.
 J  отменяет триггер A только для данного поля.
          В том случае,когда триггер одного типа определен на нескольких
уровнях,триггер более низкого уровня отменяет триггер более высокого уровня.
Это значит,что триггер post-change,определенный на уровне поля,будет отменя-
ть - для этого поля - триггеры post-change,определенные на уровне блока или
формы.Эта ситуация показана на рис.8-1,где представлена форма с 12-ю тригге-
рами,помеченными от A до L.
     Вы можете определить триггер пользователя на любом уровне формы.Однако,
так как они не запускаются каким-то определенным событием,то обычно лучше
всего определить эти триггеры на уровне формы,предоставив им тем самым наи-
более широкую,из всех возможных,область действия.Затем вы можете вызывать
эти триггеры из триггеров,определенных на любом уровне.

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

                           EТриггеры поляF
     Триггеры поля связываются с конкретными полями формы.Чтобы определить
триггер поля :
 1.Войдите в экранный построитель форм,настроившись на нужный блок.
 2.Установите курсор внутри поля.
 3.Нажмите [Define],чтобы отобразить окно DEFINE FIELD.
          Окно DEFINE FIELD также появляется автоматически,когда вы исполь-
          зуете [Select] и [Create Field] для создания нового поля.
 4.Выберите TRIGGER,чтобы высветить окно CHOOSE TRIGGER и продолжите работу
   так,как это описано в разделе "Определение триггера" далее в этой главе.
          Существует 3 типа триггеров уровня поля; вы можете для каждого по-
ля не определять ни одного из них,определить несколько или все.Дополнительно
вы можете также определить на уровне поля ключевые триггеры и триггеры поль-
зователя.Они описаны отдельно далее в этом разделе.
   Глава 9 "Синтаксис триггеров" содержит подробные примеры триггеров полей.

                          Триггеры Post-Change
                              EОписаниеF
   Триггер post-change выполняется,когда курсор собирается покинуть поле,чье
значение было изменено на не пустую величину оператором или же другим (не
post-change) триггером.Триггер выполняется как часть процесса проверки дан-
ных поля после всех других проверок,определенных в окнах DEFINE FIELD,SPECI-
FY ATTRIBUTES и SPECIFY VALIDATION,но перед любым другим триггером post-fie-
ld.Понятие "покинуть поле" определяется для того,чтобы объединить в себе де-
йствия функциональных клавиш,которые перемещают курсор за пределы окна,та-
ких,как например,[Next Field],[Previous Record] и [Delete Record].

                                EКонтекстF
   Контекстом триггера post-change является поле,для которого он определен -
т.е.то,которое проверяется.

                              EИспользованиеF
   Триггеры post-change чаще всего используются для изменения значений,выпо-
лнения вычислений и проверок данных полей в тех случаях,когда это невозможно
осуществить с помощью других атрибутов и проверок.Например,вы можете опреде-
лить триггеры post-change для того,чтобы :
 * проверить правильность вводимой информации по списку значений столбца та-
   блицы
 * выбрать название продукции и список цен из таблицы в тот момент,когда
   оператор вводит шифр продукции
 * вычислить итоговые значения элементов данных,взятых из полей "количество"
   и "цена"
 * удостовериться,что фактическая цена снижена не более,чем на 20% от номи-
   нала
 * удостовериться,что код района и номер страхового полиса отформатированы
   корректно.
     Триггеры post-change для значений,выбранных с помощью запроса,выполняю-
тся иначе,чем для значений,введенных оператором.Для получения детальной ин-
формации см."Режим запроса" в разделе "Особые случаи" в конце этой главы.

                            Триггеры Pre-Field
                              EОписаниеF
   Триггер pre-field выполняется тогда,когда курсор собирается переместиться
в поле.
                              EКонтекстF
   Контекстом триггера pre-field является поле,для которого он определен -
т.е.то,в которое перемещается курсор.

                             EИспользованиеF
   Триггеры pre-field чаще всего используются для установки сложных значений
по умолчанию; простые значения по умолчанию устанавливаются в окне SPECIFY
VALIDATION.Например,вы можете определить триггер pre-field,чтобы вводить ко-
миссионный сбор по умолчанию в зависсимости от размера заказа.(Для выполне-
ния тех же самых действий вы можете воспользоваться триггером post-change.)

                             Триггеры Post-Field
                                EОписаниеF
   Триггер post-field выполняется тогда,когда курсор собирается покинуть по-
ле (после всех проверок поля,если его значение изменялось).

                                EКонтекстF
   Контекстом триггера post-field является поле,для которого он определен -
т.е.то,которое курсор покидает.

                               EИспользованиеF
   Триггеры post-field чаще всего используются для выполнения вычислений,из-
менения значения или проверки правильности полей после выхода курсора из по-
ля.Они подобны триггерам post-change,но выполняются каждый раз,когда курсор
покидает поле - но не тогда,когда изменяется значение поля.

                              EТриггеры блокаF
     Триггеры блока связываются с конкретными блоками формы.
     Чтобы определить триггер блока :
 1.Войдите в экранный построитель форм,настроившись на нужный блок.
 2.Нажмите [Select Block].
 3.Нажмите [Define],чтобы отобразить окно DEFINE BLOCK.
 4.Выберите TRIGGER,чтобы высветить окно CHOOSE TRIGGER и продолжите работу
   так,как это описано в разделе "Определение триггера" далее в этой главе.
          12 типов триггеров уровня блока м.б. классифицированы как триггеры
запроса,триггеры внесения изменений,триггеры записей и триггеры перемещения
по блокам.Вы можете для каждого блока не определять ни одного из них,опреде-
лить несколько или все.Дополнительно вы можете также определить на уровне
блока триггеры поля,ключевые триггеры и триггеры пользователя.Они будут при-
менимы ко всем полям блока,для которых они не отменяются триггерами уровня
поля.
     Глава 9 "Синтаксис триггеров" содержит подробные примеры различных ти-
пов триггеров блока.

                             Триггеры запроса
     Существует 2 типа триггеров запроса,которые вы можете определить для
блока.Для получения общей информации о работе триггеров в процессе выполне-
ния запроса,см.раздел "Особые случаи" в конце этой главы.

                            Триггеры Pre-Query
                               EОписаниеF
   Триггер pre-query выполняется после того,как оператор нажмет [Execute
Query] или [Count Query Hits] (или эти функции выполняет другой триггер),но
до того,как SQL*Forms обратится к БД для поиска или подсчета записей.

                               EКонтекстF
   Контекстом триггера pre-query является первая запись запрашиваемого блока
- фактически содержащая условия выбора для запроса,при которых этот триггер
выполняется.

                              EИспользованиеF
   В отличии от триггера post-query,который выполняется всякий раз для каж-
дой выбранной запросом записи,триггер pre-query выполняется для запроса то-
лько один раз.
     Команды в триггерe pre-query могут ссылаться на условия запроса,введен-
ные оператором,но не на данные,возвращенные запросом.Это чаще всего исполь-
зуется для добавления новых условий запроса и инициализации счетчиков или
других элементов статистики,которые вычисляются триггерами post-query.Вы мо-
жете также воспользоваться триггерами pre-query,чтобы ограничить доступ к
таблице некоторых операторов,ограничить доступ в некоторое время и дни,и/или
ограничить доступ для некоторых типов запросов.Чтобы сделать эти ограничения
значащими,вы должны реализовать их таким же образом и в триггерах pre-insert.

                            Триггеры Post-Query
                               EОписаниеF
   Триггер post-query выполняется один раз для каждой записи,возвращенной
запросом,сразу же после того,как запись высвечена на экране.

                               EКонтекстF
  Контекстом триггера post-query является запись,которая только что выбрана.

                             EИспользованиеF
   Команды в триггере post-query могут обращаться ко всем значениям в выбра-
нной запросом записи,но не к условиям запроса.Это чаще всего используется
для накопления статистики о записях,возвращенных запросом.Например,вы можете
воспользоваться триггерами post-query,чтобы вычислить и отобразить :
 * среднюю зарплату некоторой группы служащих
 * общий итог по набору элементов строк заказов.
        Не забудьте проинициализировать статистику (установить в 0) в триг-
гере pre-query,в противном случае произведенные ранее вычисления повлияют на
более поздние.

                          Триггеры внесения изменений
     Вы можете определить 6 типов триггеров внесения изменений,выполняющих-
ся,когда оператор или триггер пытается внести изменения в БД.

                             Триггеры Pre-Delete
                                EОписаниеF
   Триггер pre-delete выполняется один раз для каждой удаляемой записи,непо-
средственно перед тем,как соответствующая строка удаляется из таблицы.

                                EКонтекстF
   Контекстом триггера pre-delete является запись,которую собираются удали-
ть.Команды в триггере pre-delete могут обращаться к значениям всех полей за-
писи формы и строк таблицы.

                              Триггеры Post-Delete
                                 EОписаниеF
   Триггер post-delete выполняется один раз для каждой удаляемой записи,не-
посредственно после удаления соответствующей строки из таблицы.

                                  EКонтекстF
   Контекстом триггера post-delete является запись,которая только что удале-
на.Команды в триггере post-delete не могут ссылаться на значения полей уда-
ленной строки.

                               Триггеры Pre-Insert
                                  EОписаниеF
   Триггер pre-insert выполняется один раз для каждой вставляемой записи,не-
посредственно перед тем,как строка вставляется в таблицу.

                                  EКонтекстF
   Контекстом триггера pre-insert является запись,которую предполагается вс-
тавить.Команды в триггере pre-insert могут ссылаться на значения всех полей
записи.

                               Триггеры Post-Insert
                                   EОписаниеF
   Триггер post-insert выполняется один раз для каждой вставляемой записи,
непосредственно после вставки соответствующей строки в таблицу.

                                   EКонтекстF
   Контекстом триггера post-insert является запись,которая только что встав-
лена.Команды в триггере post-insert могут ссылаться на значения всех полей
как записи,так и строки (которые теперь м.б. одинаковыми).

                                Триггеры Pre-Update
                                   EОписаниеF
   Триггер pre-update выполняется один раз для каждой изменяемой записи,не-
посредственно перед тем,как модифицируется соответствующая строка таблицы.

                                   EКонтекстF
   Контекстом триггера pre-update является запись,которую предполагается мо-
дифицировать.Команды в триггере pre-update могут ссылаться на значения всех
полей записи формы (которая изменяется) и строки таблицы (которая еще не из-
менена).

                               Триггеры Post-Update
                                  EОписаниеF
   Триггер post-update выполняется один раз для каждой модифицируемой запи-
си,сразу после того,как изменена соответствующая строка таблицы.

                                  EКонтекстF
   Контекстом триггера post-update является запись,которая только что была
изменена.Команды в триггере post-update могут ссылаться к значениям всех по-
лей записи и строки (уже измененных).

                               EИспользованиеF
   Три типа триггеров pre-commit используются главным образом для проверки
правильности - контроля целостности и сопоставления значений из разных по-
лей.Например,вы можете определить триггеры pre-commit для того,чтобы :
 * гарантировать,что дата выполнения заказа не является более ранней,чем да-
   та поступления заказа
 * гарантировать,что значение в поле сниженной цены не больше,чем значение в
   поле цены по номиналу
 * предотвратить удаление строки из таблицы заказов,если для нее существуют
   записи в таблице элементов заказа
 * присвоить уникальный порядковый номер заказа для новой записи
 * изменить дату последней модификации столбца таблицы
 * изменить формат даты во время ее вставки в таблицу.
     Три типа триггеров post-commit используются главным образом для размно-
жения результатов - выполнения вычислений и сохранения результатов в текущей
записи,в других блоках или таблицах.Например,вы можете определить триггеры
post-commit,чтобы :
 * удалить строку из таблицы открытых внешних займов,когда корректировка та-
   блицы баланса займов приводит к установке внешнего баланса в 0
 * изменить N служащего в таблице персональных заданий по проекту,когда этот
   N изменяется в таблице служащих
 * добавить строку в таблицу протокола корректировок,когда строка в некото-
   рой другой таблице вставляется,модифицируется или удаляется.

                              Триггеры записи
Существует 2 типа триггеров записи,которые вы можете определить для блока :

                            Триггеры Pre-Record
                               EОписаниеF
   Триггер pre-record выполняется,когда курсор собирается переместиться в
некоторую запись блока,после триггера pre-block (если курсор только что пе-
реместился в блок),но до триггера pre-field текущего поля.

                               EКонтекстF
Контекстом триггера pre-record является запись,в которую перемещается курсор.

                             EИспользованиеF
   Триггеры pre-record чаще всего используются,чтобы согласовать связаные
блоки формы.Например,вы можете определить триггер pre-record в основном бло-
ке ORDERS таким образом,что всякий раз,когда курсор переходит к новому зака-
зу,соответствующие строки появляются в детализирующем блоке LINEITEMS.

                            Триггеры Post-Record
                                EОписаниеF
   Триггер post-record выполняется,когда курсор собирается покинуть запись,
после триггера post-field текущего поля,но до триггера post-block (если кур-
сор выходит из блока).Понятие "покинуть запись" определено для того,чтобы
объединить в себе действия функциональных клавиш,которые перемещают курсор
за пределы записи,таких,как например,[Clear Record] и [Delete Record].

                                EКонтекстF
   Контекстом триггера post-record является запись,которую покидает курсор.

                              EИспользованиеF
   Триггеры post-record чаще всего используются для перекрестных-по-полям
проверок правильности и вычислений и для переформатирования или обновления
экрана после выхода из записи.Например,вы можете определить триггеры post-
record,чтобы :
 * проверить,что дата выполнения заказа не является более ранней,чем дата
   его получения
 * преобразовать дату,введенную в нестандартном формате,в стандартный формат
   ORACLE для даты.

                        Триггеры передвижения по блокам
     И наконец,вы можете определить для блока 2 типа триггеров передвижения
по блокам :
                             Триггеры Pre-Block
                               EОписаниеF
 Триггер pre-block выполняется,когда курсор собирается переместиться в блок.

                               EКонтекстF
Контекстом триггера pre-block является запись,в которую перемещается курсор.

                             EИспользованиеF
   Триггеры pre-block чаще всего используются для санкционирования доступа к
блоку и для установки сложных значений по умолчанию в моноблоках (простые
значения по умолчанию устанавливаются в окне SPECIFY VALIDATION).

                            Триггеры Post-Block
                              EОписаниеF
   Триггер post-block выполняется,когда курсор собирается покинуть блок,пос-
ле триггеров post-field и post-record для текущего поля и текущей записи.По-
нятие "покинуть блок" определено для того,чтобы объединить в себе процесс
выхода из формы и другие действия.

                              EКонтекстF
   Контекстом триггера post-block является запись,которую покидает курсор.

                             EИспользованиеF
   Триггеры post-block чаще всего используются для комплексных проверок нес-
кольких записей как одной группы.

                             EТриггеры формыF
Триггеры формы связаны со всей формой в целом.Чтобы определить триггер формы:
 1.Введите имя формы в окне CHOOSE FORM.
 2.Выберите DEFINE,чтобы высветить окно DEFINE FORM.
 3.Выберите TRIGGER,чтобы высветить окно CHOOSE TRIGGER и продолжите работу
   так,как это описано в разделе "Определение триггера" далее в этой главе.
     Существует 2 типа триггеров уровня формы и вы можете не определять ни
одного из них,определить один или оба для каждой формы.Дополнительно вы мо-
жете определить на уровне формы триггеры поля,блока,ключевые триггеры и три-
ггеры пользователя.Они будут относиться ко всем полям и блокам формы,если
триггеры уровня поля или уровня блока не отменяют их.
   Глава 9 "Синтаксис триггеров" содержит подробные примеры триггеров формы.

                              Триггеры Pre-Form
                                EОписаниеF
  Триггер pre-form выполняется,когда происходит запуск формы или вход в нее,
до того,как высвечивается меню блоков,если был выбран соответствующий пара-
метр в окне SPECIFY RUN OPTIONS.

                               EКонтекстF
   Контекстом триггера pre-form является вся форма.

                            EИспользованиеF
   Триггеры pre-form чаще всего используются для ограничения доступа,устано-
вки значений по умолчанию и печати сообщений.Например,вы можете определить
триггеры pre-form для того,чтобы :
 * ограничить доступ операторов к форме в соответствии со списком,приведен-
   ным в таблице санкционирования доступа,или ограничить доступ к форме для
   определенного времени суток
 * вызвать другую форму,которая высвечивает приветствия или инструкции.

                             Триггеры Post-Form
                                EОписаниеF
   Триггер post-form выполняется,когда оператор собирается покинуть форму,
после внесения изменений и выполнения триггеров post-field,post-record и
post-block для текущего поля,записи и блока.

                                EКонтекстF
   Контекстом триггера post-form является вся форма.

                              EИспользованиеF
   Триггеры post-form чаще всего используются для выполнения административ-
ных и учетных функций.

                           EКлючевые триггерыF
                               EОписаниеF
   Вы можете воспользоваться ключевым триггером для переопределения последс-
твий нажатия оператором функциональной клавиши.35 типов ключевых триггеров
перечислены в таблице 8-2; каждый из них,за исключением двух,определяет наз-
начение функциональной клавиши.
     Вы можете определять ключевые триггеры на любом уровне,выбирая TRIGGER
из окон DEFINE FORM,DEFINE BLOCK или DEFINE FIELD.Заполните окно CHOOSE
TRIGGER,как это описано в разделе "Определение триггера" далее в этой главе.
Однажды определенное новое назначение клавиши будет действительно все время,
пока курсор находится в форме,блоке или поле,связанных с этим триггером -
если оно не отменяется триггером такого же типа на более низком уровне.

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

                            EИспользованиеF
   Ключевые триггеры чаще всего используются,чтобы блокировать клавиши или
выполнять сложные или мнократно использующиеся функции с помощью одного на-
жатия клавиши.Например,вы можете определить ключевые триггеры,чтобы :
 * заблокировать клавишу [Delete Record] в определенном блоке
 * переопределить клавишу [Next Field] таким образом,чтобы из последнего до-
   ступного для ввода поля блока ORDERS переходить сразу в блок LINEITEMS
 * переопределить клавишу [Next Field] таким образом,чтобы из последнего до-
   ступного для ввода поля блока LINEITEMS переходить непосредственно к пер-
   вому полю следующей записи
 * переопределить клавишу [Next Record] в блоке ORDERS для выполнения запро-
   са и выборки записей из блока LINEITEMS,которые соответствуют текущему
   заказу.
                             ТАБЛИЦА 8-2
     Типы ключевых триггеров
     Типы триггера  Переопределяемая клавиша
     KEY-CLRBLK   [Clear Block]
     KEY-CLRFRM   [Clear Form/Rollback]
     KEY-CLRREC   [Clear Record]
     KEY-COMMIT   [Commit]
     KEY-CQUERY   [Count Query Hits]
     KEY-CREREC   [Create Record]
     KEY-DELREC   [Delete Record]
     KEY-DUPFLD   [Duplicate Field]
     KEY-DUPREC   [Duplicate Record]
     KEY-ENTQRY   [Enter Query]
     KEY-EXEQRY   [Execute Query]
     KEY-EXIT     [Exit/Cancel]
     KEY-Fn       [Function Key n]  n=1 дo 10
     KEY-HELP     [Help]
     KEY-LISTVAL  [List Field Values]
     KEY-MENU     [Menu]
     KEY-NXTBLK   [Next Block]
     KEY-NXTFLD   [Next Field]
     KEY-NXTKEY   [Next Primary Key Field]
     KEY-NXTREC   [Next Record]
     KEY-NXTSET   [Next Set of Records]
     KEY-OTHERS   все клавиши,не определенные триггером *)
     KEY-PRVBLK   [Previous Block]
     KEY-PRVFLD   [Previous Field]
     KEY-PRVREC   [Previous Record]
     KEY-STARTUP   Клавиш нет,вызывается после входа в форму.
 *) Этот триггер не действует в режиме запроса и при ответе на подсказку.
     Существует 11 функциональных клавиш,которые не м.б. переопределены :
 * [Clear Field]
 * [Delete Backward]
 * [Delete Character]
 * [Display Error]
 * [Insert/Replace]
 * [Left]
 * [Redisplay Screen]
 * [Right]
 * [Scroll Left]
 * [Scroll Right]
 * [Show Function Keys].
     Исключением из правила "одна клавиша - один триггер" является триггер
KEY-OTHERS.Этот триггер применяется ко всем определяемым клавишам (они при-
ведены в таблице 8-2),которые не определены для конкретного триггера.Это ча-
сто используется для блокировки всех клавиш,которые не установлены для испо-
льзования специальным образом (при этом названия таких клавиш не появляются
на экране при нажатии клавиши [Show Function Keys]).Кроме того,вы можете ис-
пользовать триггер KEY-OTHERS для выполнения некоторого действия при нажатии
оператором любой клавиши.
    Триггер KEY-OTHERS нельзя применять :
 * в режиме запроса,или
 * когда оператор вводит ответ на сообщение-подсказку,или
 * для клавиш,которые не м.б. переопределены.(Он отменяются клавишей
   [Print].)
Глава 9 "Синтаксис триггеров" содержит подробные примеры ключевых триггеров.

                        EТриггеры пользователяF
                       EОписание и использованиеF
 Триггеры пользовател выполняются не при наступлении определенного события,а
запускаются на выполнение из других триггеров.Вы можете использовать их для
воплощения принципа модульности при написании триггеров,чтобы избежать пов-
торения команд в нескольких различных триггерах.Например,вы можете определи-
ть приведенный ниже триггер пользователя с именем GETCLIENT для того,чтобы
найти имя клиента по идентификатору клиента :
        SELECT NAME
        INTO :ORDERS.NAME
        FROM CLIENT
        WHERE CLIENT.CLIENTID = :ORDERS.CLIENTID

     Затем вы можете обратиться к триггеру GETCLIENT из триггера post-change
для поля CLIENTID и из триггера post-query для блока CLIENT.
     Так как имена им присваиваются произвольно,то триггер пользователя не
имеет какого-либо определенного типа.Вы присваиваете каждому такому триггеру
его собственное имя в соответствии с правилами присвоения имен
(см.EПриложение DF) и затем ссылаетесь на него по этому имени.Вы можете
использовать функцию EXETRG,описанную под заголовком "Команды SQL*Forms в
триггерах" в главе 9,чтобы вызвать триггер пользователя из другого триггера.
     Вы можете определить триггер пользователя на любом уровне и затем выз-
вать его из другого триггера на этом же уровне или ниже.Очевидно,лучше всего
определить триггер пользователя на уровне формы,чтобы им можно было пользо-
ваться на любом уровне.Триггер,расположенный на более низком уровне,будет
отменять триггер с тем же самым именем,расположенный на более высоком уровне.
     Чтобы определить триггер пользователя,выберите TRIGGER из окна DEFINE
FORM,DEFINE BLOCK или DEFINE FIELD.Заполните окно CHOOSE TRIGGER,как это
описано в разделе "Определение триггера" далее в этой главе.

                                EКонтекстF
Контекст триггера пользователя зависит от триггера,который его вызывает.Если
вызов происходит из ключевого триггера,контекстом являются поле и запись,в
которых находится курсор.Если вызывающим является триггер pre- или post-,то
контекст будет таким же,как и у этого триггера. См."Программные триггеры и
триггеры по событию" в главе 9 для получения дополнительной информации.
    Глава 9 "Синтаксис триггеров" содержит подробные примеры триггеров поль-
зователя.

                         EОпределение триггераF
     "Определить триггер" означает описать его шаги и свойства,включая то,:
 * какой тип имеет триггер (где он будет выполняться)
 * какие команды будут выполняться на каждом шаге
 * что будет происходить при успешном,а что при неудачном завершении каждого
   шага.
     Окна,которые используются для определения триггера,показаны на рис.8-2.
      ЙНННННННННННННН»  ЙНННННННННННННН»  ЙНННННННННННННН»
      є   Окно       є  є   Окно       є  є   Окно       є
      є DEFINE FIELD є  є DEFINE BLOCK є  є DEFINE FORM  є
      ИННННННННННННННј  ИННННННННННННННј  ИННННННННННННННј
     TRIGGER і  ^          TRIGGER і  ^     TRIGGER і  ^
             і  і                  v  і  [Accept]   і  і
             і  і [Accept]ЙНННННННННННННН»          і  і
             і  А--------Дє              є <--------Щ  і
             А----------Д>є      Окно    є  [Accept]   і
                          є     CHOOSE   є------------ДЩ
                          є     TRIGGER  є<------------Дї
                          є              є--------Дї    і
                          ИННННННННННННННј  DEFINE і    і
                      CREATE і  ^                  і    і
                  или MODIFY і  і                  і    і
                  ATTRIBUTES v  і [Accept]         v [Accept]
      ЙНННННННННННННН»    ЙНННННННННННННН»  ЙНННННННННННННН»
      є       Окно   є<--Дє      Окно    є  є   Окно       є
      є TRIGGER STEP є    є TRIGGER STEP є  єDEFINE TRIGGERє
      є ATTRIBUTES   є--Д>є              є  є              є
      ИННННННННННННННј    ИННННННННННННННј  ИННННННННННННННј
                    [Accept]  і  ^
                              v  і
                        CREATE
           Рис.8-2.Определение триггера

                          EОкно CHOOSE TRIGGERF
     Вы можете использовать окно CHOOSE TRIGGER,чтобы создать,модифицировать
или удалить триггер.Чтобы высветить это окно,выберите TRIGGER в окне DEFINE
FIELD,DEFINE BLOCK или DEFINE FORM в зависимости от того,на каком уровне вы
хотите определить триггер.
     Если вы уже определили некоторые триггеры для текущего поля,блока или
формы,то в области ввода вы увидите имя одного из них.
     Чтобы создать новый триггер :
 1.Name : В этой области ввода введите тип триггера,который вы желаете соз-
          дать или - для триггера пользователя - имя,которое вы хотите испо-
          льзовать.Если имя триггера уже появилось в области ввода,вводите
          новое вместо него.Тип триггера м.б. допустимым для уровня,на кото-
          ром происходит определение триггера.
                  Если у вас есть сомнения по поводу типа триггера,выберите
          TYPES, чтобы высветить окно LIST TYPES.Оно содержит список типов
          триггеров,доступных на текущем уровне и ниже.Или,если вы определя-
          ете ключевой триггер,выберите KEYS для отображения окна LIST KEYS,
          содержащего список ключевых триггеров,доступных для всех уровней.
          Выберите тип триггера и затем нажмите [Accept],чтобы скопировать
          его в окно CHOOSE TRIGGER.
 2.Выберите CREATE,чтобы отобразить окно TRIGGER STEP,где вы можете вводить
   команды,которые будут выполняться.
           Чтобы модифицировать уже существующий триггер,введите его имя в
   области ввода.Вы можете использовать LIST,чтобы отобразить окно LIST
   TRIGGERS,содержащее список триггеров,уже определенных вами на этом же
   уровне,или,использовать PREVIOUS и NEXT для просмотра их один за другим.
   Затем выберите MODIFY для отображения первого шага триггера в окне
   TRIGGER STEP.
          Чтобы удалить существующий триггер,введите его имя в области ввода
и выберите DROP.
          Чтобы изменить имя триггера,или,чтобы войти в меню описаний ключе-
вых триггеров,введите имя триггера в области ввода и выберите DEFINE для
отображения окна DEFINE TRIGGER.

                           EОкно TRIGGER STEPF
     Триггер состоит из набора шагов,обычно (но не всегда) выполняющихся по-
следовательно.Шаг состоит из одной команды SQL или SQL*Forms или вызова под-
соединяемой программы пользователя.(На самом деле большинство триггеров со-
держит только один шаг.) Каждый шаг триггера может завершаться успешно,неу-
дачно или вырабатывать ошибку.
     Вы можете использовать окно TRIGGER STEP,чтобы записать или изменить
шаги триггера,и окно TRIGGER STEP ATTRIBUTES для указания того,что произой-
дет,если шаг завершится успешно или неудачно.Выбор CREATE или MODIFY в окне
CHOOSE TRIGGER высвечивает окно TRIGGER STEP,в котором можете ввести коман-
ды,которые будут выполняться в каждом шаге триггера.
     Если вы создаете новый триггер,окно TRIGGER STEP вначале будет пустым.
После того,как вы заполните окно,определив какой-либо шаг триггера,выберите
CREATE,чтобы очистить окно и перейти к следующему шагу.
     Если же вы модифицируете уже существующий триггер,в окне отобразится
его первый шаг.
 * Чтобы изменить уже существующий шаг,воспользуйтесь действиями NEXT STEP и
   PREV STEP для отображения нужного вам шага.Затем откорректируйте информа-
   цию в окне.
 * Чтобы удалить существующий шаг,воспользуйтесь действиями NEXT STEP и PREV
   STEP для отображения нужного вам шага.Затем выберите DROP.
 * Чтобы вставить новый шаг,выберите CREATE,чтобы очистить окно и заполните
   его описанием нового шага.Измените его порядковый N (при необходимости).
     Чтобы определить шаг триггера :
 1.Seq # (номер шага) : В этой области ввода введите порядковый N,в соответ-
   ствии с которым будет выполняться шаг.См."Изменение порядка следования" в
   главе 4 для уточнения деталей по изменению порядка следования шагов.Вы
   можете также использовать метки для изменения порядка выполнения.
 2.Label (метка) : Если вы хотите передавать управление на этот шаг из како-
   го-то другого места триггера,введите в этой области ввода метку,с помощью
   которой в дальнейшем вы сможете ссылаться на этот шаг.
 3.Trigger area (тело триггера) : В этой области ввода (не имеющей на экране
   названия) введите команду SQL или SQL*Forms,которая будет выполняться в
   этом шаге.Полный синтаксис команд,которые вы можете использовать,приведен
   в главе 9.
        Если шаг триггера по размеру больше,чем может одновременно отобрази-
   ть окно,вы можете использовать FORWARD и BACKWARD для прокрутки вверх и
   вниз.
 4.Message if trigger step fails (сообщение,появляющееся при неудачном заве-
   ршении шага триггера) : В этой области ввода введите сообщение,которое
   будет высвечиваться в том случае,если шаг триггера завершится неудачно.
   Успешное и неудачное завершение шага триггера описаны под заголовком "Как
   триггеры выполняются" далее в этой главе.
        Заметьте,что ключ "Reverse return code" из окне TRIGGER STEP ATTRI-
   BUTES оказывает влияние на определение неудачного завершения шага,и сооб-
   щение м.б. заменено вызовом SQLIEM из подсоединяемой программы пользова-
   теля.См."Как триггеры выполняются" далее в этой главе для получения более
   подробной информации о выводе данного сообщения.
 5.Чтобы определить атрибуты шага (этот пункт необязателен),выберите ATTRI-
   BUTES для отображения окна TRIGGER STEP ATTRIBUTES,описанного в следующем
   разделе.
 6.Когда вы удовлетворены введенным вами шагом,существует 2 способа перейти
   к следующему шагу :
    * Чтобы перейти к следующему существующему шагу,выберите NEXT STEP.
    * Чтобы создать новый шаг,выберите CREATE для очистки окна.
           Вы можете повторить этот процесс,чтобы определить столько шагов
для триггера,сколько вам нужно.По окончании нажмите [Accept] для сохранения
изменений и возврата к окну CHOOSE TRIGGER.Чтобы аннулировать ваши измене-
ния,нажмите [Exit/Cancel].
           Если шаг,который вы хотите определить,похож на уже существующий
шаг,используйте NEXT STEP и PREV STEP для отображения существующего шага.За-
тем выберите COPY для создания копии шага,порядковый N которой станет на 1
больше,чем у оригинала.И наконец,модифицируйте копию и измените ее порядко-
вый N (если необходимо).

                      EОкно TRIGGER STEP ATTRIBUTESF
    После выбора ATTRIBUTES в окне TRIGGER STEP вы увидите окно TRIGGER STEP
ATTRIBUTES.Атрибуты шага триггера характеризуют :
 * что происходит,когда шаг завершается успешно или неудачно
 * сколько памяти отводится для шага.
     Когда вы создаете шаг триггера,SQL*Forms назначает его атрибутам значе-
ния по умолчанию.Вам необходимо определять атрибуты,только если вы хотите
изменить эти значения (принятые по умолчанию).
     Вопросы успешного и неудачного завершения шага триггера подробно обсуж-
даются в разделе "Как триггеры выполняются" далее в этой главе.

                   Определить атрибуты шага триггера :
 1.Abort trigger when step fails (прерывание выполнения триггера при неудач-
   ном завершении шага) : Если этот ключ выбран - и метка неудачного завер-
   шения (описана ниже) не определена - неудачное завершение шага будет ос-
   танавливать выполнение триггера.Кроме того,успешное или неудачное завер-
   шение триггера зависит от ключа "Return success when aborting trigger"
   (описан ниже).
        Этот ключ выбран по умолчанию,так как неудачное завершение шага три-
   ггера обычно означает,что что-то сделано ошибочно и вы хотите прекратить
   выполнение.Заметьте,что на определение понятия неудачного завершения шага
   оказывает влияние ключ "Reverse return code" (описан ниже).
 2.Reverse return code (реверсия кода возврата) : Если выбран этот ключ,то
   обычные критерии успешного и неудачного завершения меняются местами.Чаще
   всего эта возможность используется,чтобы :
    * удостовериться,что соответствующая запись не существует (т.е.команда
      SELECT завершается неудачно) перед выполнением некоторого действия.
    * отобразить сообщение о неудачном завершении,когда оператор нажал недо-
      ступную клавишу,хотя сам триггер завершается успешно.
 3.Return success when aborting trigger (возврат успешного завершения при
   прерывании работы триггера) : Этот ключ действует только в том случае,ес-
   ли выбран ключ "Abort trigger when step fails".Если выбраны оба эти клю-
   ча,то сам триггер завершится успешно,даже если его шаг завершился неудач-
   но и выполнение было остановлено.Это чаще всего используется в триггерах,
   выполнение которых не зависит от конкретных условий.
 4.Separate cursor data area (выделение области курсора) : Обычно каждому
   шагу триггера назначается свой собственный курсор (область памяти) для
   выполнения.Если количество памяти ограничено,вы можете уменьшить ее испо-
   льзование (но замедлить процесс выполнения) путем отмены ключа "Optimize
   SQL processing" в окне SPECIFY RUN OPTIONS (см.главу 4).Если вы поступите
   таким образом,то вы можете выбрать ключ "Separate cursor data area",чтобы
   резервировать область памяти (и повысить скорость выполнения) только для
   тех шагов SQL-триггера,которые выполняются наиболее часто.
        Этот ключ относится только к командам SQL в шагах триггера; он не
   оказывает никакого воздействия на команды SQL*Forms и подсоединяемые про-
   граммы пользователя,вызываемые из триггеров.
 5.Success and Failure labels (метки успешного и неудачного завершения) :
   Шаги триггера обычно выполняются последовательно.Тем не менее,вы можете
   использовать метки шагов (определенные в окне TRIGGER STEP),чтобы измени-
   ть порядок выполнения.В области ввода "success label" введите метку шага,
   который будет выполняться следующим,если текущий шаг завершится успешно.В
   области ввода "failure label" введите метку шага,который будет выполнять-
   ся следующим,если текущий шаг завершится неудачно.
       Допустим,вам понадобилось,чтобы триггер выполнялся следующим образом:
шаг 1,затем шаг 2 и шаг 4,если шаг 1 завершился успешно,или же шаг 3 и шаг
4,если шаг 1 завершился неудачно.Приведенная ниже таблица показывает,как вы
должны заполнить для этих 4 шагов области  ввода "Label", "Success label" и
"Failure label" :

        Шаг  Label     Success label  Failure label
         1                              FAILSTEP
         2               BOTHSTEP
         3  FAILSTEP
         4  BOTHSTEP

        Имена FAILSTEP и BOTHSTEP являются произвольными.Вы можете выбрать
любые допустимые в SQL*Forms имена,при условии,что каждая метка внутри триг-
гера будет уникальной.Заметьте,что для шага 1 не нужна метка успешного заве-
ршения,так как в случае успешного завершения вы хотите продолжить выполнение
триггера непосредственно со следующего шага.
        Ключ "Reverse return code" будет влиять на передачу управления по
метке и на то,будет ли высвечиваться сообщение о неудачном завершении.Одна-
ко,если вы ввели метки успешного и неудачного завершения,оба ключа "Abort
trigger when step fails" и "Return  success when aborting trigger" игнориру-
ются.
     Если вы удовлетворены атрибутами для шага триггера,нажмите [Accept],
чтобы сохранить ваши изменения и вернуться в окно TRIGGER STEP.Для аннулиро-
вания изменений введите [Exit/Cancel].
     Успешное и неудачное завершение триггеров и шагов триггера представляет
собой сложный вопрос.Этот вопрос,а также использование атрибутов успешного и
неудачного завершения подробно рассматриваются в разделе "Как триггеры выпо-
лняются" далее в этой главе.

                          EОкно DEFINE TRIGGERF
     Когда вы введете имя уже существующего триггера в окне CHOOSE TRIGGER и
выберете DEFINE,то вы увидите окно DEFINE TRIGGER.Здесь вы можете изменить
имя триггера или (для ключевого триггера) ввести описание его функций для
меню.Эти элементы совершенно необязательны.
          Определить характеристики триггера :
 1.Name (имя) : В этой области ввода введите новое имя (тип) для триггера.
   Переименовывание триггера особенно полезно,когда вы хотите :
    * "привязать" ключевой триггер к другой клавише
    * выделить триггер в отдельный модуль,сделав его триггером пользователя;
      таким образом,в дальнейшем вы сможете использовать его во множестве
      других триггеров.
 2.Description (описание) : В этой области ввода,- которая применяется толь-
   ко для ключевых триггеров - введите краткое описание (до 20 символов) но-
   вой функции клавиши.Если выбран ключ "Display in menus" (см.ниже),это
   описание будет появляться в меню [Show Function Keys] вместо описания
   клавиши,использующегося по умолчанию.
 3.Display in menus (отображение в меню) : Этот ключ также применяется толь-
   ко для ключевых триггеров.Если он выбран (он выбирается по умолчанию),то
   описание клавиши будет появляться в меню [Show Function Keys].Вы можете
   отменить этот ключ,чтобы убрать описание клавиши из меню,даже если вы
   ввели описание в указанной выше области ввода.
     Если вы удовлетворены именем и описанием триггера,нажмите [Accept],что-
бы сохранить ваши изменения и вернуться в окно CHOOSE TRIGGER.Для аннулиро-
вания изменений нажмите [Exit/Cancel].

                    EКак триггеры выполняютсяF
                   EКогда триггеры выполняютсяF
     Каждый тип триггера активизируется определенным событием.Например,триг-
гер post-field для поля выполняется тогда,когда курсор покидает поле.
     Большинство событий активизирует группы триггеров.Например :
 * [Next Field] активизирует триггер post-change текущего поля (если его
   значение было изменено),триггер post-field для этого же поля и триггер
   pre-field следующего поля
 * [Next Record] активизирует триггеры post-change,post-field и post-record
   для текущей записи,а также триггеры pre-record и pre-field для следующей
   записи
 * [Commit] активизирует целый пакет триггеров,включая 6 типов триггеров
   внесения изменений для каждой сохраняемой записи.
     Эти триггеры активизируются,если соответствующая функция выдается опе-
   ратором или же другим триггером.(Разумеется,ключевые триггеры имеют выс-
   ший приоритет.Если в момент выполнения триггера KEY-NXTFLD оператор нажал
   [Next Field],обычные триггеры [Next Field] не будут выполняться до тех
   пор,пока ключевой триггер не "включит" функцию NXTFLD.)
     Группы триггеров м.б. вложенными; это значит,что одна группа может ак-
тивизировать другую.Когда вторая группа завершит выполнение,будет продолжено
выполнение первой группы.

                             EВыполнение шаговF
     Во время выполнения триггера его шаги выполняются последовательно по
одному.Если некоторый шаг изменяет содержимое поля,то эти изменения доступны
и следующим шагам.
     Шаги в триггере обычно выполняются согласно заданному порядку следова-
ния.Однако,этот порядок м.б. изменен в зависимости от результата выполнения
шага.

                      EРезультаты выполнения шагаF
     По окончании выполнения шага триггера возможны 3 результата :
 * он может завершиться успешно
 * может завершиться неудачно
 * может послужить причиной фатальной ошибки.
     В оставшейся части данного раздела обсуждаются причины и последствия
этих результатов.См.ниже "Резюме по выполнению шага триггера" для получения
полного и последовательного описания воздействия каждого фактора.

                  Что влияет на результат выполнения шага
     Таблица 8-3 показывает,какие события служат причиной каждого типа резу-
льтата выполнения шага триггера,содержащего команду SQL,команды SQL*Forms
или подсоединяемую программу пользователя.
                                                      ТАБЛИЦА 8-3
     Причины,влияющие на результат шага
                   Результат выполнения
     ----------------------------------------------------------Д
     Команда         Успешное    Неудачное        Фатальная
      шага          завершение   завершение        ошибка
     ----------------------------------------------------------Д
     Команды SQL    Воздействует Не воздей-   Синтаксическая
     SELECT,INSERT, по крайней   ствует       ошибка,
     UPDATE,DELETE  мере на      на строку    таблица не
                    1 строку                  существует
     Другие команды  Нет синтак-  Невозможно  См.выше
     SQL             сических     осуществить
                     ошибок
     Команды        Корректное    Выполнение  Выход за
     SQL*Forms      выполнение    не возможно пределы памяти
                                   по какой-
                                   нибудь
                                   причине
     Подсоединяемая                Синтакси-  Вызываемый
     программа                     ческая    триггер
     пользователя                  ошибка    не существует
     Имейте в виду,что :
 * SQL*Forms не осуществляет синтаксической проверки,когда вы вводите шаг
   триггера в окне TRIGGER STEP.Синтаксические ошибки (например,пропущенное
   ключевое слово) могут служить причиной неудачного завершения или фаталь-
   ной ошибки в зависсимости от типа команды.
 * Команда SELECT,INSERT,UPDATE или DELETE завершается успешно,если она вы-
   бирает,вставляет,изменяет или удаляет по крайней мере одну строку,и заве-
   ршается неудачно,если это не так.Другие команды SQL не могут завершаться
   неудачно; они всегда завершаются успешно,если только они не содержат син-
   таксических ошибок.
 * Команды SELECT,выполнение которых зависит от контекста запроса,обрабаты-
   ваются по разному.Для получения дополнительной информации см.раздел "Осо-
   бые случаи" в конце этой главы.
 * Вы можете использовать ключ "Reverse return code" в окне TRIGGER STEP
   ATTRIBUTES,чтобы изменить на противоположный обычный критерий успешного и
   неудачного завершения шага.Например,если вы выбрали "Reverse return code"
   для шага,содержащего команду SELECT,шаг будет завершаться неудачно,если
   команда SELECT возвращает хотя бы одну строку,и завершаться успешно,если
   это не так.Этот ключ часто используется для того,чтобы убедиться в отсут-
   ствии строки перед выполнением некоторых действий - таких,как удаление
   записи по отделу,когда для него еще существуют записи о служащих.
          Заметьте,что "Reverse return code" не влияет на сохранение значе-
   ния в поле командой SELECT...INTO или оператором EXEC IAF PUT подсоединя-
   емой программы пользователя.
          Что происходит после завершения выполнения шага То,что произойдет
   после успешного или неудачного завершения шага триггера,зависит от элеме-
   нтов окна TRIGGER STEP ATTRIBUTES.
          Если шаг триггера завершился успешно,то затем SQL*Forms продолжит
   выполнение триггера следующим образом:
      * Если вы ввели метку успешного завершения,SQL*Forms передаст управле-
        ние на шаг с этой меткой.
      * В противном случае SQL*Forms будет последовательно выполнять переход
        к следующему шагу до тех пор,пока не будет выполнен последний шаг.
      Если шаг триггера завершился неудачно,то SQL*Forms высветит сообщение
   о неудачном завершении,определенное в окне TRIGGER STEP.Затем :
      * Если  вы  ввели метку неудачного завершения,SQL*Forms передаст упра-
        вление на шаг с этой меткой и продолжит выполнение триггера.
      * Если же вы не ввели метку неудачного завершения,то :
         * Если выбран ключ "Abort trigger when step fails" (он выбирается
           по умолчанию),SQL*Forms останавливает выполнение триггера.Завер-
           шится ли триггер успешно или неудачно,зависит от ключа "Return
           success when aborting trigger".
         * Иначе SQL*Forms игнорирует неудачное за вершение и продолжает вы-
           полнение триггера со следующего по порядку шага.
     Если шаг триггера явился причиной фатальной ошибки,установленные ключи
игнорируются.SQL*Forms прекращает выполнение триггера и триггер завершается
неудачно.
                    Резюме по выполнению шага триггера
     Этот раздел подробно,этап за этапом описывает,как SQL*Forms обрабатыва-
ет шаги триггера.
 1.Если триггер выполняется в режиме запроса и шаг содержит команду SELECT
   без фразы INTO или с фразой INTO,ссылающейся только на поля БД для теку-
   щего блока,шаг не выполняется.SQL*Forms переходит к этапу 8,как если бы
   команда уже выполнилась и завершилась успешно.
 2.Команда шага выполняется.SQL*Forms оценивает выполнение шага по критериям
   успешного завершения,неудачного завершения и фатальной ошибки шага триг-
   гера (см.таблицу 8-3).
 3.Если командой шага является LOCK TABLE и она выполняется корректно,SQL*
   Forms переходит непосредственно к этапу 8.Если для таблицы уже установле-
   на блокировка,запрещающая совместное использование,LOCK TABLE устанавли-
   вает для таблицы WAIT LOCK (если не определено NOWAIT),или же завершается
   успешно без блокировки таблицы (если задано NOWAIT).LOCK TABLE не может
   завершаться неудачно,но может послужить причиной фатальной ошибки в том
   случае,если допущена синтаксическая ошибка или таблица не существует.
 4.Если шаг удовлетворяет критерию успешного завершения,значения,выбранные
   командами SELECT...INTO или полученные операторами EXEC IAF PUT подсоеди-
   няемой программы пользователя,пересылаются в предназначенные для них по-
   ля.Если же шаг удовлетворяет критерию неудачного завершения,значения по-
   лей не изменяются.
 5.Если шаг заканчивается с фатальной ошибкой,высвечивается сообщение,описы-
   вающее ошибку.(Это стандартное сообщение SQL*Forms или ORACLE,а не сооб-
   щение,определенное в окне TRIGGER STEP.Иногда вы можете получить больше
   информации,нажав [Display Error].) Последующие шаги триггера или макро-
   функции не выполняются и триггер завершается неудачно.
 6.SQL*Forms просматривает установку ключа "Reverse return code" и решает,
   закончится ли шаг успешно или неудачно.Если шаг завершился успешно,SQL*
   Forms передает управление на этап 8; если же он завершился неудачно,выпо-
   лнение продолжается с этапа 7.
 7.Поскольку шаг завершился неудачно,SQL*Forms обрабатывает неудачное завер-
   шение.
    a.Высвечивает сообщение о неудачном завершении.
    b.Если существует метка неудачного завершения,SQL*Forms передает управ-
      ление на соответствующий ей шаг.Ключи "Abort query when trigger fails"
      и "Return success when aborting trigger" не имеют значения.Если не су-
      ществует шага с соответствующей меткой,последующие шаги триггера не
      выполняются и триггер заканчивается успешно.
    c.Если не существует метки неудачного завершения,то возможен один из
      следующих случаев :
        * Если ключ "Abort trigger when step fails" отменен,SQL*Forms пере-
          ходит к этапу 8 (как если бы шаг завершился успешно).
        * Если выбран ключ "Abort trigger when step fails",а ключ "Return
          success when aborting trigger" отменен,- последующие шаги триггера
          не выполняются и триггер завершается неудачно.
        * Если выбраны и ключ "Abort trigger when step fails" и ключ "Return
          success when aborting trigger",то последующие шаги триггера не вы-
          полняются и триггер завершается успешно.
 8.Поскольку шаг завершился успешно,SQL*Forms обрабатывает успешное заверше-
   ние.
    a.Если существует метка успешного завершения,SQL*Forms передает управле-
      ние на соответствующий ей шаг.Если не существует шага с соответствую-
      щей меткой,последующие шаги триггера не выполняются и триггер заканчи-
      вается успешно.
    b.Если не существует метки успешного завершения,SQL*Forms осуществляет
      переход к следующему шагу (если он существует).
    c.Если следующего шага нет,триггер завершается успешно.
         Заметьте,что ключ "Reverse return code" проверяется на этапе 6.Это
означает,что этапы 1-5 не связаны с этим ключом,а этапы 7 и 8 - связаны.

                    EРезультат выполнения триггераF
     В отличии от шага триггера,для самого триггера существует только 2 воз-
можных результата выполнения.Он может завершиться успешно или завершиться
неудачно.

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

          Что происходит после завершения выполнения триггера
     Если триггер завершается успешно,продолжается обычное выполнение формы.
     Если триггер завершается неудачно,последствия этого зависят от типа
триггера,как показано в таблице 8-4.
     В таблице обратите внимание,что,если триггеры перемещения (pre- и post-
для поля,записи,блока или формы) завершаются неудачно,то некоторые триггеры
pre-field,pre-record и pre-block м.б. выполнены повторно.
     Если один из этих триггеров входа завершается неудачно - реакция SQL*
Forms непредсказуема.Мы рекомендуем тестировать и отлаживать ваши триггеры
перемещения тщательно,по нескольку раз,чтобы убедиться в том,что оператор не
попадет в такую ситуацию ни при каких обстоятельствах.

                                                        ТАБЛИЦА 8-4
             Последствия неудачного завершения триггера

     Уровень      Тип            Результат неудачного завершения
     ----------------------------------------------------------Д
     Поле    Post-change   EВ режиме запроса,в случае неудачного завершения
                            шага :F Неудачное завершение игнорируется и за-
                            прос продолжает выполняться.
                           EВ режиме запроса,в случае фатальной ошибки :F
                            Записи больше не выбираются,а курсор остается на
                            записи,вызвавшей ошибку.
                           EНе в режиме запроса :F Изменения аннулируются.
                            Если происходит процесс внесения изменений,то
                            все изменения отменяются.Оператор должен откор-
                            ректировать значение поля и попытаться повторить
                            выполнение еще раз.
              Pre-field     Курсор не входит в поле.Он должен повторно войти
                            в поле,которое только что покинул,повторно выпо-
                            лнив для него триггер pre-field.
              Post-field    Операция перемещения курсора прерывается и кур-
                            сор остается в текущем поле.Триггер pre-field
                            для этого поля повторно выполняться не будет.
     Блок     Pre-query     Запрос не выполняется.
              Post-query   EВ случае неудачного завершения шага :F Выбран-
                            ная запись игнорируется и в эту же запись поме-
                            щается другая строка.
                            EВ случае фатальной ошибки :F Выборка записей
                            больше не производится и курсор остается в запи-
                            си,послужившей причиной ошибки.
               Внесения     Внесение изменений останавливает-
               изменений    ся.Все изменения,накопленные во
               Pre-insert   время транзакции,отменяются.
              Post-insert
              Pre-update
              Post-update
              Pre-delete
              Post-delete
     ----------------------------------------------------------Д
              Pre-record    Неудачное завершение игнорируется.Курсор переме-
                            щается в запись независимо от того,завершился ли
                            триггер успешно или неудачно.
              Post-record   Операция перемещения курсора прерывается и кур-
                            сор остается в текущей записи.Он должен повторно
                            войти в поле,которое только что покинул,повторно
                            выполнив для него триггер pre-field.
              Pre-block     Курсор не входит в блок.Он должен повторно войти
                            в блок,который только что покинул,повторно выпо-
                            лнив для него триггер pre-block.
              Post-block    Операция перемещения курсора прерывается и кур-
                            сор остается в текущем блоке.Он должен повторно
                            войти в запись и поле,которые только что покинул,
                            повторно выполнив для них триггеры pre-record и
                            pre-field.
   Форма      Pre-form      Оператор выходит из формы без выполнения тригге-
                            ра post-form.
              Post-form     Операция выхода из формы прерывается.Курсор дол-
                            жен повторно войти в блок,запись и поле,которые
                            он только что покинул,повторно вы полнив для них
                            триггеры pre-block,pre-record и pre-field.
              Ключевой      Никакие функции больше не выполняются.Оператор
              триггер       может продолжить обычную работу с формой.
              Триггер       Шаг,содержащий функцию EXETRG (которая вызвала
            пользователя    этот триггер),также завершается неудачно и ника-
                            кие другие его функции не выполняются.Триггер,
                            содержащий функцию EXETRG,может или,тем не менее,
                            продолжить выполнение,или завершиться успешно,в
                            зависимости от установленных ключей для шага
                            EXETRG.

                               EОсобые случаиF
                                 Режим запроса
     Когда запись возвращается запросом,перед триггером post-query выполняю-
тся триггеры post-change для полей блока (если такие существуют).
     Триггеры post-change выполняются в данном контексте (называемом режимом
запроса),чтобы дать форме возможность проинициализировать поля,для которых
не указан атрибут "Database field" (поля не БД),но работающие как "поля БД".
     Триггеры в режиме запроса могут вести себя по-разному :
 * Триггеры post-change выполняются только для полей БД.
 * Поле текущего блока (описанное,как "Database field") не м.б. изменено ша-
   гом триггера.Все попытки изменить значение поля таким способом будут про-
   игнорированы (и не послужат причиной фатальной ошибки).
 * Если команда SELECT не содержит фразы INTO,или,если она пытается выбирать
   (SELECT) значения только в (INTO) поля текущего блока,описанные как "Da-
   tabase field",то она не будет выполняться вообще.Выполнение триггера бу-
   дет продолжено так,как если бы команда завершилась успешно.
 * Шаг триггера,содержащий команду SQL,отличную от SELECT,будет служить при-
   чиной фатальной ошибки.
 * Шаг триггера,содержащий команду SQL*Forms,игнорируется.Триггер продолжает
   выполняться так,как если бы команда завершилась успешно.(Команда #COPY,
   относящаяся к "полям не-базы-данных",будет выполнена.)
 * Команды подсоединяемой программы пользователя обрабатываются в режиме за-
   проса таким же способом,как и в других контекстах (за исключением того,
   что они не могут изменять значения полей,как это отмечено выше).Поскольку
   SQL*Forms передает подсоединяемой программе пользователя флаг,сигнализи-
   рующий о режиме запроса,постольку подсоединяемая программа может выполня-
   ть различные функции в зависимости от того,установлен этот флаг или нет.

                         Вопросы проверки данных поля
     Триггеры могут изменять значение поля в любом месте формы.Когда они вы-
полняют это,поле помечается как изменяемое.Однако,его триггер post-change не
выполняется сразу же,а откладывается до тех пор,пока производится проверка
данных поля при помощи стандартных операций SQL*Forms.Это может понадобиться
в тех случаях,которые могут привести к конфликтной ситуации.Например :
 * Предположим,что триггер для PRODID в блоке LINEITEMS изменяет значение в
   поле PRODUCT DESCRIPTION.Позднее оператор перемещает курсор в PRODUCT
   DESCRIPTION,затем покидает это поле,не изменив его значения.Тем не менее,
   триггер post-change для поля PRODUCT DESCRIPTION выполняется.
 * Предположим,что триггер для CLIENTID в блоке ORDERS изменяет значение по-
   ля NAME блока CLIENT.Позднее оператор перемещает курсор в блок CLIENT,за-
   тем покидает блок или запись,даже не переместив курсор в NAME.Тем не ме-
   нее,триггер post-change для поля NAME выполняется.Такой режим работы нео-
   бходим для эффективной проверки данных поля,но он приводит к возникнове-
   нию конфликтных ситуаций для оператора,когда триггер находит ошибку в по-
   ле,которое оператор непосредственно не изменял.Имейте это в виду при оп-
   ределении шагов триггера и составлении для них сообщений о неудачном за-
   вершении.

                    Вопросы блокоориентированного режима
     В блокоориентированных терминалах (например,IBM 3270),информация пере-
дается в ЭВМ в виде блоков,а не посимвольно.Это значительно влияет на способ
работы триггеров.Например,триггер post-field в блокоориентированном режиме
игнорируется,так как SQL*Forms не может определить,когда оператор переходит
от одного поля к другому в одном и том же блоке.
     Если вы разрабатываете формы для блокоориентированной среды,см."ORACLE.
Руководство по установке и использованию" для получения подробной информации
по вопросам блокоориентированного режима.

+                              EГЛАВАF E9F
                           EСИНТАКСИС ТРИГГЕРОВF
     В предыдущей главе описано все,что вам необходимо знать о триггерах,за
исключением команд,включаемых в триггеры.Данная глава завершает представле-
ние триггеров и объясняет,как использовать команды триггеров,которые бывают
трех видов:
 * команды SQL
 * команды SQL*Forms (включая синтаксис команд,коды функций и переменные)
 * подсоединяемые программы пользователя
     Каждая команда включает в себя один шаг триггера.Допускается смешивание
команд всех 3 видов в различных шагах триггера.
     Описание синтаксиса в этой главе содержит достаточно серьезные примеры,
иллюстрирующие все основные типы триггеров.Приводится также краткое описание
того,как отлаживать триггеры.

                       EКоманды SQL в триггерахF
     Структурный язык запросов,иначе SQL - это ключевой метод работы с дан-
ными СУБД ORACLE.Вы можете использовать команды SQL в триггерах в добавление
к обычному набору операций с БД для того,чтобы:
 * помещать данные в поля формы
 * выполнять вычисления с данными формы
 * менять формат данных формы
 * проверять наличие данных в базе
 * сравнивать данные в полях формы
     Команды SQL вводятся непосредственно в окне TRIGGER STEP (см.главу 8).
Каждый оператор SQL (команда вместе с дополнительными фразами) охватывает
один шаг триггера.
     Команды SQL в триггерах используют фактически тот же синтаксис,что и
команды SQL в других частях ORACLE,за исключением одного отличия и двух рас-
ширений,обсуждаемых ниже.Синтаксис SQL описан в документе "SQL*Plus.Руковод-
ство пользователя " и в данном руководстве не описывается.Если вы не знакомы
с SQL,обратитесь к указанному документу для получения детальной информации.
     Основная особенность синтаксиса команд SQL в триггерах - это то,что они
не заканчиваются точкой с запятой (;).
     Перед тем,как помещать команды SQL в триггеры,полезно проверить их сна-
чала в SQL*Plus.Таким способом команды SQL легче отладить.

              EКоманды SQL,которые вы можете использоватьF
     Вообще говоря,в триггере вы можете использовать любую команду SQL.Одна-
ко,существуют некоторые ограничения и предостережения:
 * В post-chahge триггере разрешается использовать только команду SELECT.
 * Команды модификации данных (INSERT,UPDATE,DELETE) можно использовать то-
   лько в триггерах занесения изменений (pre- и post-insert,update,delete).
 * Если вы используете команды INSERT,UPDATE,или DELETE при модификации ба-
   зовой таблицы блока текущей формы,обеспечьте корректировку соответствущих
   данных формы.
     Обратите внимание,что в триггерах можно использовать только команды
SQL,а не SQL*Plus.В этом смысле,документ "SQL*Plus.Руководство пользователя"
точно определяет тип каждой команды.
     Команды SQL в триггерах работают с таблицами БД точно так же,как и в
других частях ORACLE.Например,вы можете использовать указанные ниже команды
в post-delete триггере для того,чтобы скорректировать таблицу слежения,кото-
рая контролирует использование вашей основной таблицы:
        UPDATE AUDIT
        SET  LASTCHAHGE = SYSDATE
            LASTUSER = USER
        WHERE TABLE = 'ORDERS'

     Заметьте,что USER - это системная переменная ("псевдо-столбец"),которая
содержит текущий регистрационный идентификатор пользователя ORACLE.
     Аналогично,можно использовать в триггере обычную команду
     SELECT:
        SELECT *
        FROM ORDERS
        WHERE ORDERID = 305

     Однако,при выполнении приведенной команды,результаты запроса не выводя-
тся на экран.Следствием ее выполнения является только успешное (если произо-
шел выбор хотя бы одной строки из таблицы) или неудачное (если выбора не
произошло или возникла фатальная ошибка) завершение.Вы можете использовать
подобные команды для проверки существования данных в таблице,как это проил-
люстрировано ниже в подразделе "Примеры SQL триггеров".
   При желании выводить на экран результаты запроса,вам необходимо использо-
вать 2 расширения SQL*Forms(по отношению к SQL) для обращения к полям формы.

            EРасширенный синтаксис SQL для обращения к формеF
     SQL*Forms включает 2 расширения SQL,которые позволяют обращаться к по-
лям формы:
 * Вы можете использовать синтаксис ":[блок.]поле" для того,чтобы обратиться
   к полю формы.Двоеточие (:) здесь означает,что обращение происходит к полю
   формы,а не к столбцу таблицы.Вы можете использовать этот синтаксис в лю-
   бом месте,где мог бы находиться указатель столбца таблицы или константа.
          Если имя поля,которое вы указали,уникально,т.е. существует только
   в одном блоке формы,то указание блока можно опустить.
          Для совместимости с ранними версиями можно вместо двоеточия также
   использовать амперсанд (&).Однако,двоеточие предпочтительнее.
 * Вы можете поместить фразу INTO в оператор SELECT для того,чтобы вносить
   извлекаемые значения в поля формы.Она должна следовать непосредственно за
   командой SELECT и предшествовать фразе FROM.
          Для выборки данных в поля формы можно использовать только INTO.По-
   этому указание двоеточия (:) перед полем формы во фразе INTO необязатель-
   но,однако,может использоваться для ясности.

     Расширенный синтаксис оператора SELECT выглядит следующим образом:
      SELECT { [таблица].[список_столбцов] | :[блок.]поле | * }
        [INTO [:][блок.]поле]
        FROM список_таблиц
        [WHERE фраза]
        [HAVING фраза]
        [GROUP BY фраза]
     Например,следующий post-change триггер в поле CLIENTID блока ORDERS бу-
дет выбирать имя клиента из таблицы CLIENT и помещать его в поле NAME блока
ORDERS при любом вводе,изменении или выборке CLIENTID:
        SELECT NAME
            INTO :ORDERS.NAME
            FROM CLIENT
            WHERE CLIENT.CLIENTID = :ORDERS.ORDERID

     Вы можете выбирать данные в любое поле блока.Поле может соответствовать
столбцу базовой таблицы блока (Data Base Field) или не соответствовать тако-
му столбцу.Поле м.б. видимым для оператора (Displayed) или быть невидимым
для него.Если для поля указано Dispalyed,то оно м.б. доступно оператору для
изменения (Input allowed или Update allowed) или нет; и.т.д..
     Если вы выбираете значения для занесения в поле,имя которого используе-
тся более,чем в одном блоке,убедитесь,что вы сопровождаете имя поля именем
блока,как в примере.Если вы этого не сделаете,то возникнет ошибка.
     Оператор SELECT с фразой INTO выбирает только одну строку.Тогда как ко-
манда SELECT в других случаях может выбрать более,чем одну строку,SELECT с
фразой INTO выбирает только первую из указанных строк.Если вам необходимо
выбирать несколько строк в мультиблоке,используйте функцию SQL*Forms EXEQRY
для установки запроса для блока.
     Столбец таблицы может иметь несколько значений-по одному на каждую ст-
року,выбираемую из таблицы-однако,поле SQL*Forms имеет только одно значение,
а именно,контекст записи блока.Таким образом,невозможно выбирать записи из
блока так,как это делается со строками таблицы.

                        EПримеры SQL триггеровF
 1.Данный триггер обеспечивает соответствие ID (идентификатора) товара при
   вводе заказа в таблицу LINEITEMS товару в таблице PRODUCT.
                 Тип: Post-change триггер для поля LINEITEMS.PRODID
      SELECT PRODID
      FROM PRODUCT
      WHERE PRODUCT.PRODID = :LINEITEMS.PRODID

     Атрибуты: *Abort trigger when step fails
     Сообщение при неудаче: Ид.товара не найден ; используйте
                [LIST VALUES] (распечатать значения)
 2.В некоторых случаях триггер SELECT не нуждается в выборке данных из таб-
   лицы.Обратите внимание,например,что триггер (1) извлекает значение из
   столбца PRODID,но никак не влияет на него.Триггер просто выполняет свою
   работу - успешно или неуспешно,- пытаясь выбрать строки,которые удовлет-
   воряют фразе WHERE.
         В этом случае,как правило,быстрее вместо выбора столбца из таблицы,
   производить выбор константы (по соглашению,'X').

      Тип: Post-change триггер для поля LINEITEMS.PRODID
      SELECT 'X'
      FROM PRODUCT
      WHERE PRODUCT.PRODID = :LINEITEMS.PRODID

     Атрибуты: *Abort trigger when step fails
     Сообщение при неудаче: Ид.товара не найден ; используйте
                [LIST VALUES] (распечатать значения)
 3.Данный триггер при вводе ID товара отображает на экране наименования то-
   вара и его стандартную цену.
                                Тип: триггер пользователя

      Применение: Post-chahge для поля LINEITEMS.PRODUCT.
            Post-query для блока LINEITEMS.
      SELECT DESCRIP,STDPRICE
      INTO LINEITEMS.PRODUCTDESCRIPTION,LINEITEMS.STDPRICE
      FROM PRODUCT,PRICELIST
      WHERE PRODUCT.PRODID = :LINEITEMS.PRODID
      AND PRICELIST.PRODID = :LINEITEMS.PRODID

     Атрибуты: *Abort trigger when step fails
     Сообщение при неудаче: Ид.товара не найден ; используйте
                [LIST VALUES] (распечатать значения)

     Данный триггер иллюстрирует то,что в поля формы можно выбирать несколь-
     ко значений одновременно.Заметим,что он также осуществляет проверку при
     вводе в MGR,используя таблицу EMP.
 4.Хотя в некоторых случаях триггер SELECT и не нуждается в доступе к реаль-
   ной таблице,синтаксис требует включения фразы FROM,в которой таблица д.б.
   указана.В этом случае,традиционный и наиболее эффективный способ - это
   использование "одностроковой","одностолбцовой" системной таблицы общего
   пользования (public) с именем DUAL:
      DUMMY
      -----
        X
       Следующий триггер,например,вычисляет стоимость элемента строки заказа
   при помощи умножения цены на количество заказанного.

     Тип: Post-query,post-record триггер для блока LINEITEMS
     SELECT :ACTUALPRICE * :QTY
     INTO ITEMTOT
     FROM DUAL

     Атрибуты: *Abort trigger when step fails
 5.Данный триггер обеспечивает,чтобы дата реализации заказа не являлась бо-
   лее ранней,чем дата получения заказа.

      Тип: Post-record триггер для блока LINEITEMS.
         SELECT 'X'
         FROM DUAL
         WHERE TO_DATE(:ORDERDATE) <= TO_DATE(:SHIPDATE)

     Сообщение при неудаче: Дата реализации не м.б. более
                ранней,чем дата получения заказа.
 6.Данный триггер предотвращает удаление заказов,которые все еще содержатся
   в БД(в таблице LINEITEMS).

      Тип: Pre-delete триггер для блока ORDERS
         SELECT 'X'
         FROM LINEITEMS
         WHERE ORDERID = :ORDERS.ORDERID

     Атрибуты: *Reverse return code
          *Abort trigger when step fails
     Сообщение при неудаче: Перед удалением заказа д.б. удалена информация
                            по заказу из таблицы LINEITEMS.
     Обратите внимание,что триггер спроектирован не для того,чтобы выполнять
     выбор строки и завершается неудачно,если это происходит.
 7.Данный триггер,состоящий из 2 шагов,атоматически генерирует следующий по-
   рядковый N для нового заказа.

      Тип: Pre-insert триггер для блока ORDERS
         Шаг 1:
         UPDATE SEQNOS
         SET MAXSEQNO = MAXSEQNO +1
         WHERE TABLENAME = 'ORDERS'

     Атрибуты: *Abort trigger when step fails
          Шаг 2:
       SELECT MAXSEQNO
       INTO ORDERS.ORDERID
       FROM SEQNOS
       WHERE TABLENAME = 'ORDERS'

     Атрибуты: *Abort trigger when step fails

     Заметим,что SELECT(MAX)+1 INTO ORDERID FROM SEQNOS не будет воспринима-
     ться,поскольку разные пользователи могут выбирать одно и тоже значение
     из SEQNOS перед тем,как будет внесено изменение.
 8.Данный триггер ограничивает план заказов для заказа тремя вариантами,ко-
   торым соответствует 3 наименования на верхнем или нижнем регистре.

      Тип: Post-change триггер для поля ORDERS.COMMPLAN
      SELECT 'X'
      FROM DUAL
      WHERE :ORDERS.COMMPLAN IN ('A','B','C','a','b','c')

     Атрибуты: *Abort trigger when step fails
 9.Данный триггер проверяет,что действительная цена снижена не более,чем на
   20% по сравнению с исходной.

      Тип: Post-chahge триггер для поля LINEITEMS.ACTUALPRICE.
         SELECT 'X'
         FROM DUAL
         WHERE :LINEITEMS.ACTUALPRICE >= 0.8 * LINEITEMS.STDPRICE

     Сообщение при неудаче: Цена не м.б. понижена более,чем на 20%.
 10.Данный триггер проверяет правильность телефонного номера,набранного в
    соответствующем поле ввода.

       Тип: Post-change триггер для поля CLIENT.AREA
           SELECT 'X'
           FROM DUAL
           WHERE SUBSTR(:AREA,1) 1 AND SUBSTR(:AREA,2) 2

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

       Тип: Pre-form триггер
       SELECT 'X'
       FROM AUTHORIZED
       WHERE USER = AUTHUSER

     Атрибуты: *Abort trigger when step fails

     Сообщение при неудаче: Несакционированный доступ к форме
          USER - это системная переменная ("псевдо-столбец"),которая содер-
     жит текущий регистрационный идентификатор пользователя ORACLE.
 12.Данный триггер ограничивает доступ к форме по времени с 8:00 до 16:00.

       Тип: Pre-form триггер
       SELECT 'X'
       FROM DUAL
       WHERE TO_NUMBER (TO_CHAR (SYSDATE,'HH24')) BETWEEN 8
       AND 16

                           EСпециальные темыF
     Блокирование таблиц и строк в триггерах SQL*Forms автоматически управ-
ляет блокированием таблиц и записей в такой ситуации,когда 2 или более опе-
раторов пытаются использовать одновременно одну и ту же таблицу.Если опера-
тор запрашивает блок или начинает вводить в него запись,то базовая таблица
блока блокируется в режиме "разделяемой корректировки"(share update mode)
так,как это описано в разделе "Блокирование таблиц и строк" главы 4.Такое
средство позволяет нескольким операторам выполнять запросы и корректировать
таблицу совместно (псевдоодновременно).Тем не менее,если триггер выполняет
изменения таблицы,которая не была заблокирована,то SQL*Forms,как правило,
вводит режим взаимоисключающей (монопольной) блокировки таблицы.При этом,ес-
ли таблица была уже поставлена в режим share mode другим оператором,то воз-
никает ошибка.Хотя отсутствие какого-либо режима блокировки небезопасно,вве-
дение монопольного режима,тем не менее,является более радикальной мерой
(препятствующей работе других операторов),чем это необходимо.Рекомендуется в
триггер,изменяюший базовую таблицу,включать команду SQL - LOCK TABLE IN
SHARE UPDATE MODE,- в качестве первого шага, обеспечивающего "смягчение"
уровня блокировки.
     Если вы используете (или игнорируете) блокировку записей без достаточ-
ного понимания,функционирование ваших форм может вызывать длительные задерж-
ки или тупиковые ситуации (и как результат,нежелательные "отмены"(см.словарь
терминов)) в тех ситуациях,когда 2 оператора пытаются использовать одну и ту
же таблицу одновременно.Можно уменьшить риск возникновения тупиковой ситуа-
ции,следуя нижеперечисленным правилам:
 * Блокируйте таблицы только в случае необходимости и только до необходимого
   уровня.Например,не используйте монопольную блокировку там,где подойдет
   блокировка в режиме разделяемой корректировки.
 * Всегда блокируйте таблицы в одной и той же последовательности.Если одна
   из форм (или триггер) блокирует таблицу A,а затем B,а другая форма делает
   это в противоположном порядке,то риск заклинивания увеличивается.Коорди-
   нируйте последовательность блокирования таблиц с другими разработчиками
   форм,поскольку 2 формы,разработанные разными людьми,скорее могут войти в
   тупиковую ситуацию чем те же формы,разработанные одним человеком.
 * Рекомендуйте тем,кто использует ваши формы как можно чаще вносить измене-
   ния в БД,возникающие в процессе их работы.

                           Ипользование ROWID
     В процессе создания таблицы ORACLE автоматически включает в нее столбец
с именем ROWID ("идентификатор строки").В любой момент времени каждая строка
однозначно определяется ее значением ROWID.ORACLE может переназначить ROWID
удаляемой строки для вставляемой строки.
    Аналогично,при создании блока формы,SQL*Forms добавляет к ней "скрытое",
некорректируемое поле с именем ROWID.При выборке записи для работы (помеще-
ние записи в рабочую область),значение ROWID также помещается в рабочую об-
ласть.(Заново создаваемые записи не соответствуют какой-либо строке и поэто-
му имеют пустое значение ROWID).
     SQL*Forms использует ROWID для управления транзакциями в блоках формы и
таблицами,которые с ними связаны.Таким образом,в большинстве случаев не воз-
никает необходимости иметь дело с ROWID.Исключением является такая ситуация,
когда требуется откорректировать таблицу,не связанную с блоком текущей фор-
мы.Вы можете использовать при этом ROWID для того,чтобы проследить,каким за-
писям формы соответствуют строки таблицы.
     Например,выборку строки,которая соответствует текущей записи блока
ORDERS можно осуществить,используя команду SQL:
        SELECT ...
        WHERE ROWID = :ORDERS.ROWID

     Рассмотрим форму,которая поддерживает файл истории изменений для неко-
торой таблицы с именем EMP.При любом изменении EMP оригинальное содержание
корректируемой строки д.б. записано в таблицу с названием EMP_HISTORY.Вы мо-
жете осуществить это,определив pre-update и pre-delete триггеры в блоке таб-
лицы EMP с помощью команды:
        INSERT INTO EMP_HISTORY
            SELECT * FROM EMP
            WHERE ROWID = :EMP.ROWID

     Всякий раз,когда строка EMP удаляется или корректируется,триггер добав-
ляет строку к EMP_HISTORY.Добавляемая строка извлекается из EMP с помощью
подзапроса (фраза SELECT в команде UPDATE).Это строка EMP,ROWID которой сов-
падает с ROWID в текущем блоке,то есть,строка EMP,подлежащая корректировке
или удалению.
     Предположим теперь,что триггер должен считать и позднее откорректирова-
ть строку из такой таблицы,которая не соответствует блоку формы.Тогда для
считывания строки используйте команду SQL - SELECT FOR UPDATE; строка при
этом заблокируется,что не позволит другому оператору изменять ее до тех пор,
пока откорректированная строка не будет успешно сохранена в БД.Сохраняйте
также ROWID строки в поле.Наконец,выполните команду UPDATE...WHERE ROWID =
(поле) для того,чтобы откорректировать данную строку,а не другую.
     ROWID полезно применять в триггерах pre-update,pre-delete,post-insert,
post-update,post-query.Использование ROWID в триггерах pre-insert и pre-que-
ry бесполезно,поскольку во время выполнения этих триггеров записи в блоке не
обладают какими-либо имеющими смысл значениями ROWID.Аналогично в триггерах
post-delete - поскольку строка в результате выполнения тригера уже не сущес-
твует.
     Если вы желаете иметь отображение ROWID в целях отладки,то используйте
триггер pre-query для извлечения ROWID в высвечиваемое поле.Поле должно име-
ть как минимум 26 позиций для того,чтобы высветить значение ROWID.
     Ни в коем случае вы не должны позволять оператору (или триггеру) изме-
нять ROWID.SQL*Forms требует правильного,адекватного ROWID в процессе сохра-
нения результата работы в БД,поэтому изменение ROWID в форме может нарушить
процесс корректировки.

                   EКоманды SQL*Forms в триггерахF
     В отличие от команд SQL,которые м.б. использованы во многих продуктах
ORACLE,команды SQL*Forms применяются только в шагах триггеров.Вы можете ис-
пользовать их для того,чтобы:
 * переопределять функциональные клавиши
 * выполнять последовательности действий над формой так,как-будто оператор
   нажал на функциональную клавишу
 * выполнять триггеры пользователя
 * вызывать другие формы
 * манипулировать с другими переменными
 * выполнять команды ОС.
     Можно вводить команды SQL*Forms непосредственно в окне TRIGGER STEP
(см.главу 8).Каждый оператор SQL*Forms (команда с аргументами или функциона-
льными кодами) представляет собой один шаг триггера.

               EКоманды SQL*Forms,которые можно использоватьF
     Все команды SQL*Forms начинаются со знака #.Существует 4 команды,кото-
рые можно включать в шаги триггера:
 #EXEMACRO,#COPY,#ERASE и #HOST.Синтаксис этих команд показан в таблице 9-1.

     При написании команд SQL*Forms в триггерах вы можете использовать любое
количество и комбинацию пробелов,табуляций и новых строк для разделения от-
дельных элементов (лексем).Если 2 лексемы можно различить только с помощью
разделения,вы обязательно должны вставить между ними пробелы.Вы не должны
использовать пробелы для разделения компонент переменной (GLOBAL имя_переме-
нной) или компонент обращения к полю ([блок.]поле).
     Константа или командная строка представляет собой строку символов прои-
звольной длины,заключенную в одиночные кавычки (апострофы).Для того,чтобы
включить в строку собственно апостроф,необходимо его удвоить:

        'Don''t forget the extra quote.'

     Обращение вида [блок.]поле в команде SQL*Forms не должно предваряться
двоеточием (:).(Команды SQL*Forms не могут ссылаться к таблицам и столбцам
БД,- таким образом,обращение не м.б. двусмысленным.Ссылку на блок можно опу-
стить,но только в том случае,когда имя поля,которое вы указали,существует
только в одном блоке формы.

                                                           ТАБЛИЦА 9-1
                    EСинтаксис команд SQL*FormsF
 #EXEMACRO  Используется для выполнения последовательности действий над фор-
            мой
 #EXEMACRO макро_оператор; ...;
           где макро_оператор = { код_функции і оператор_CASE },
         коды функций перечислены в таблице 9-2,
        оператор_ CASE = CASE { переменная і 'константа' } IS
             WHEN { переменная і 'константа' }
             THEN макро_оператор; ...;
             ...
             [WHEN OTHERS THEN макро_оператор; ...;]
             END CASE;
     где переменная = { [блок.]поле і
             GLOBAL.имя_переменной і
             SYSTEM.имя_переменной і
             указатель_переменной }
     где указатель_переменной = &переменная

 #COPY    Используется для копирования констант,значений полей,глобальных
          или системных переменных из источника в приемник.
     #COPY источник приемник
             где источник = { переменная і 'константа' }
               приемник = { [блок.]поле і
             GLOBAL.имя_переменной і
             указатель_переменной }

 #ERASE  Используется для удаления глобальных переменных.
 #ERASE { GLOBAL.имя_переменной і указатель_переменной }

 #HOST Используется для выполнения команд ОС.
 #HOST { 'командная строка' і [блок.]поле і указатель_переменной }

                             Команда #EXEMACRO
     Макро - это серия действий,которые выполняются SQL*Forms.Действия могут
включать операторские функции (имитировать нажатие оператором функциональной
клавиши) или специальные функции SQL*Forms,которые могут выполняться только
триггерами.Вы можете использовать макросы для того,чтобы:
 * сокращать повторяющийся или объемный операторский ввод
 * управлять потоком выполнения прикладных задач (например,координировать
   записи в двух или нескольких блоках формы)
 * обеспечивать выполнение некоторых действий в определенном порядке
 * обеспечивать помощь оператору (например,вызывая другую форму,в которой
   оператор может запросить идентификатор покупателя).
Вы можете выполнять макросы по условию,и вкладывать условия в другие условия.
     Макро определяется с помощью команды #EXEMACRO.Вслед за командой вводи-
тся функциональный код каждого действия с аргументом (если он есть) и затем
точка с запятой (;).Вы можете добавлять столько функциональных кодов,сколько
пожелаете.При выполнении шага триггера,содержащего команду #EXEMACRO,выпол-
няются все действия,соответствующие функциональным кодам.
     Функциональные коды,которые можно использовать,перечислены в таблице
9-2.Обратите внимание,что существуют важные ограничения на коды,которые мож-
но использовать в post- и pre - триггерах,приводящие к тому,что макросы ис-
пользуются в "ключевых" триггерах.Более подробно это описано далее в подраз-
деле "Программные триггеры и триггеры по событию".
     Заметим,что "ключевые" триггеры изменяют эффект действия функциональной
клавиши,но не изменяют функцию,обычно связанную с этой клавишей.Например,
триггер KEY-NXTFLD переопределяет действия,которые должны произойти,когда
оператор нажмет [Next Field],однако,триггер,включающий функцию NXTFLD,при
этом будет по-прежнему передвигать курсор к следующему полю.

                                                          ТАБЛИЦА 9-2
                        Функциональные коды макрокоманд

     Код      Аргумент     Функция
     -----------------------------------------------------------
     ABTQRY               Прекращает выполнение данного запроса.Последующие
                          строки не считываются.
     CALL     форма       Приостанавливает обработку текущей формы и отобра-
              (form)      жает на экране указанную форму.При завершении по
                          макросу EXIT или клавише [Exit/Cancel] возобновля-
                          ет работу приостановленной формы с точки прерыва-
                          ния.
  CALLINPUT               Приостанавливает обработку текущей макрокоманды и
                          воспринимает ввод оператора.При завершении по мак-
                         росу EXIT или по клавише [Exit/Cansel] возобновляет
                         работу приостановленной формы с точки прерывания.
  CALLQRY      форма      Приостанавливает обработку текущей формы и отобра-
                          жает на экране указанную форму,в которой должны
                          выполняться только запросы.При завершеннии по мак-
                          росу EXIT или по клавише [Exit/Canсel] возобновля-
                         ет работу приостанавленной формы с точки прерывания.
  CHRMODE                 [Insert/Replace]   (Вставить/Заменить)
  CLRBLK                  [Clear Block]      (Очистить блок)
  CLRFLD                  [Clear Field]      (Очистить поле)
  CLRFRM                  [Clear Form]       (Очистить форму)
  CLRREC                  [Clear Record]     (Очистить запись)
  COMMIT                  [Commit]           (Внести изменения)
  DELBACK                 [Delete Backward]  (Удалить назад)
  DELCHR                  [Delete Character] (Удалить символ)
  DELREC                  [Delete Record]    (Удалить запись)
  DERROR                  [Display Error]    (Высветить ошибку)
  DKEYS                   [Show Function Keys] (Показать функциональные
                          клавиши)
  DUPFLD                  [Duplicate Field]  (Дублировать поле)
  DUPREC                  [Duplicate Record] (Дублировать запись)
  ENTQRY                  [Enter Query]      (Ввести запрос)
  EXETRG    имя,заданное   Выполнить триггер,заданный
            пользователем  пользователем.
  EXEQRY                  [Execute Query]    (Выполнить запрос)
  EXIT                    [Exit/Cancel]
  GOBLK     блок          Перемещает курсор в указанный блок.
  GOFLD     [блок.]поле   Перемещает курсор в указанное поле.
  HELP                    [Help]              (Помощь)
  LISTVAL                 [List Field Values] (Вывести значения поля)
  MENU                    [Menu]              (Варианты выбора)
  MOVLEFT                 [Left]              (Влево)
  MOVRIGHT                [Right]             (Вправо)
  NEWFRM    форма         Замещает текущую форму в (памяти) указанной.
  NOOP                    Отсутствие операций; не выполняет никаких действий,
                          но выводит сообщение:  Unrecognized command.
  NULL                    Отсутствие операций; не выполняет никаких действий.
                          Полезна при задании пустого действия- в тех случа-
                          ях,когда м.б. задан хотя бы один функциональный
                          код (как,например,в CASE)
  NXTBLK                  [Next Block]        (Следующий блок)
  NXTFLD                  [Next Field]        (Следующее поле)
  NXTKEY                  [Next Primary Key Field] (Следующее поле первичного
                          ключа)
  NXTREC                  [Next Record]       (Следующая запись)
  NXTSET                  [Next Set of Records] (Следующий набор записей)
  PAUSE                   Задерживает обработку текущей макрокоманды и выс-
                          вечивает сообщение: "Press any function key to
                          continue" в строке состояний.Нажатие оператором
                          функциональной клавиши возобновляет работу прерва-
                          нной макрокоманды.
  PRINT                   [Print]              (Печать)
  PRVBLK                  [Previous Block]     (Предыдущий блок)
  PRVFLD                  [Previous Field]     (Предыдущее поле)
  PRVREC                  [Previous Record]    (Предыдущая запись)
  REDISP                  [Redisplay Screen]   (Высветить экран заново)

                    EКак макрокоманды обрабатываютсяF
     Когда SQL*Forms выполняет шаг триггера,содержащий макрос,он выполняет
функции в указанном порядке.Например,команда:
        #EXEMACRO NXTBLK; NXTSET; PRVBLK;
выполняется так,как будто оператор последовательно нажимает клавиши [Next
Block],[Next Set of Records] и [Previous Block].
     Функции NOOP и NULL не выполняют никаких действий.Однако,функция NOOP
выводит сообщение "Unrecognized command".Примером использования может служи-
ть блокировка функциональной клавиши [Delete Record] с помощью определения
триггера KEYDELREC следующим образом:
        #EXEMACRO NULL;
Теперь при нажатии оператором [Delete Record] ничего происходить не будет.
Однако,если вы определите ключ "Reverse return code" ("Переключение кода во-
зврата на противоположный") и введете сообщение о неудачном завершении -
"Невозможно удалить запись по заказу",то шаг завершится неудачно и это сооб-
щение будет высвечено.
     Функциональные коды в макрокоманде выполняются последовательно,незави-
симо от результата выполнения предыдущего кода.Например,команда:
        #EXEMACRO NXTFLD; NXTFLD; NXTFLD;
обычно продвигает курсор на 3 поля.Если,однако,первое поле содержит некорре-
ктные данные,первое NXTFLD даст ошибку,выведет сообщение и оставит курсор на
месте.Три NXTFLD,в этом случае,дадут просто 3 сообщения об ошибке.Таким об-
разом,при написании многофункциональных команд,вы должны проанализировать
эффект последовательного выполнения функций для всех условий,которые сможете
предусмотреть.Некоторые функции,например,CLRBLK или EXEQRY,как правило подс-
казывают оператору о необходимости сохранить изменения в БД.При выполнении
макрокоманды с такими функциями,SQL*Forms выведет подсказку и задержит выпо-
лнение команды до тех пор,пока оператор не введет ответ на подсказку.
     Команда #EXEMACRO завершается успешно,когда все ее функциональные коды
были выполнены.Если хотя бы один из них,по любой причине (включая синтакси-
ческие ошибки),не был выполнен,то команда завершается неуспешно.

                   EВетвление по оператору CASEF
     Для того,чтобы выполнять действия по условию,вы можете использовать в
макрокоманде оператор CASE.После резервированного слова CASE указывается ко-
нстанта,поле или переменная,которые служат в качестве селектора.Затем следу-
ет любое количество фраз WHEN,которые содержат константы,поля и переменные
для сравнения со значением селектора,а также набор функциональных кодов,ко-
торые выполняются при успешном сравнении.Если ни одна из фраз WHEN не удов-
летворяет значению селектора,выполняются функциональные коды,указанные во
фразе WHEN OTHERS.
     Например,в форме,содержащей опросный лист,триггер KEY - NXTFLD (приве-
денный ниже) в поле с именем GENDER передвигает курсор на один блок,если от-
вечающий - мужчина,и на 2 блока,если отвечающий - женщина:
        #EXEMACRO CASE GENDER IS
        WHEN 'M' THEN NXTBLK;
        WHEN 'm' THEN NXTBLK;
        WHEN 'F' THEN NXTBLK; NXTBLK;
        WHEN 'f' THEN NXTBLK; NXTBLK;
        WHEN OTHERS THEN NULL;
        END CASE;

     Если ответ не совпадает ни с M,ни с F (или с их строчными эквивалента-
ми),курсор остается на месте.(Обратите внимание,что,если поле GENDER имеет
атрибут Uppercase,триггеру не нужно будет проверять ответы,записанные строч-
ными буквами).
     Оператор CASE может находиться в любом месте макрокоманды.Функциональ-
ные коды до CASE или после END CASE выполняются независимо от того,какая ве-
твь CASE выбрана при выполнении.
     Хотя вы и не можете вставить команды SQL в макрокоманду,все таки есть
возможность вызывать их условно.Для этого надо определить команды SQL в три-
ггере пользователя,а затем применить функцию EXETRG для вызова их в каких-
либо ветвях оператора CASE.

                        EВложение макрокомандF
    Существуют 3 способа,которыми макрокоманды м.б. вложены друг в друга:
 * при выполнении функционального кода м.б. запущен другой триггер,который в
   свою очередь может включать другую макрокоманду
 * функция EXETRG может явно вызывать другой триггер,который содержит макро-
   команду
 * среди функциональных кодов,заключенных в ветвях одного оператора CASE мо-
   жет находиться другой оператор CASE
     Когда встречается вложение,выполнение первой(внешней) макрокоманды при-
останавливается в той точке,из которой произошел вызов второго (внутреннего)
триггера.После успешного завершения внутреннего триггера внешняя макрокоман-
да продолжается.
     Избегайте вложений,приводящих к "самовключению" макрокоманд,поскольку в
этом случае триггер может никогда не закончиться.

            EПрограммные триггеры и триггеры по событиюF
     В некоторых триггерах существуют ограничения на использование функцио-
нальных кодов.Ограничения зависят от того,к какому классу триггеров принад-
лежит данный триггер - к программным триггерам или триггерам по событию.Эта
классификация проводится по отношению к основным функциям SQL*Forms таким,
как [Next Field] и [Execute Query].
 * Программный триггер запускается явно,по той функциональной клавише,для
   которой определен триггер.Программные триггеры синхронны в том смысле,что
   стартуются между выполнениями основных функций SQL*Forms.

                     Программные триггеры включают:
 * все ключевые триггеры
 * триггеры пользователя,которые включены в программные триггеры.
          В программных триггерах вы можете использовать любые функциональ-
   ные макрокоды.
 * Триггер по событию - это триггер,связанный с некоторым событием таким,как
   движение курсора,проверка поля или попытка внести результаты транзакции в
   БД.Триггеры по событию асинхронны в том смысле,что вызываются в процессе
   выполнения основных функций SQL*Forms.Например,триггер post-change запус-
   кается во время выполнения функции [Next Field].

                      Триггеры по событию включают :
 * все pre-триггеры
 * все post-триггеры
 * триггеры пользователя,которые включены в триггеры по событию.
          В триггерах по событию допускаются только такие функциональные ко-
   ды,которые не влияют на выполнение основных функций SQL*Forms в програм-
   мах,а именно:
    * CALL
    * CALLQRY
    * NULL
          Вы можете также использовать CASE и EXETRG в триггере по событию
при условии,что оператор CASE или программный триггер включают только функ-
циональные коды 3 указанных видов.

                      Вызов одной формы из другой
     Возможность вызова формы в процессе работы другой формы позволяет объе-
динять множество форм в законченное,модульное прикладное средство.Вызов фор-
мы представляет простой способ подключения форм,созданных разными разработ-
чиками.Это исключает необходимость "лишней" работы по созданию и обслужива-
нию форм.
               Вызовы форм чаще всего используются для :
 * Предоставления меню,которое дает набор вариантов,из которых оператор мо-
   жет сделать выбор.
 * Представления вспомогательной информации на экране (см."Примеры SQL*Forms
   триггеров" ниже в этой главе,где даются примеры).
 * Запроса информации,необходимой оператору.Напри мер,при неправильном вводе
   идентификатора клиента в форме ORDENTRY,триггер может вызвать форму,из
   которой оператор может запросить таблицу CLIENT.
 * Разделения блоков и таблиц несколькими прикладными программами.Рассмот-
   рим,например,блок CLIENT в форме ORDENTRY.Если существует несколько при-
   ложений,поддерживающих список клиентов,то полезно сконструировать отдель-
   ную форму с единственным блоком клиентов.Эту форму затем можно вызывать в
   приложениях как при работе с заказами,так и при работе с клиентами.

     Есть 3 макрофункции,позволяющие вызывать другую форму.И CALL и CALLQRY
временно приостанавливают работу текущей формы пока выполняется другая.SQL*
Forms воспринимает ввод в вызванной форме до тех пор,пока не встречает функ-
циональный код EXIT (или нажатие клавиши [Exit/Cancel]).В этот момент проис-
ходит возврат к исходной форме,к продолжению работы задержанной макрокоман-
ды.Функция NEWFRM замещает текущую форму в памяти с помощью указанной.При
выполнении же функции EXIT,SQL*Forms возвращается к той форме,которая исход-
но подключила форму,указанную в NEWFRM.Если такой формы не существует,то
происходит возврат к ОС.
     Оба вызова,CALL и CALLQRY м.б. использованы как в программном,так и в
триггере по событию.Однако,прямого доступа из одной формы в другую не сущес-
твует.Для передачи информации между формами необходимо использовать глобаль-
ные переменные.
     Если вызываемая форма не м.б. загружена,соответствующий шаг триггера
завершается неудачно и никакие его функциональные коды больше не выполняют-
ся.При этом триггер,содержащий вызов,м.б. продолжен или успешно завершен в
зависимости от установленных ключей шага.
     Если на экране во время обработки CALL и CALLQRY появляется сообщение
об ошибке,оператор должен подтвердить его получение перед тем,как будет выс-
вечена вызываемая форма.Сообщение исчезнет при возобновлении работы вызываю-
щей формы.
     Основные отличия CALL и CALLQRY заключаются в той функциональности,ко-
торую они предлагают и в том сохранении производимых изменений,которого они
требуют :
 * CALL позволяет вызываемой форме работать в обычном режиме.Если в вызываю-
   щей форме существуют не сохраненные изменения,SQL*Forms выдает сообщение:
          Can't call form with changes to commit.
     (Нет возможности вызвать форму,поскольку есть несохраненные изменения)
   Сохранение изменений не м.б. выполнено в триггере по событию.Таким обра-
   зом,если CALL используется в триггере по событию и существуют не сохране-
   ные изменения,подсказка по сохранению изменений не появится,вызов немед-
   ленно будет завершен аварийно и триггер завершится неудачно.
 * CALLQRY не требует сохранения изменений в вызывающей форме (или запроса к
   оператору на выполнение этого); изменения так и останутся несохранеными
   до тех пор пока,форма не продолжится.Однако,операции в вызываемой форме
   подвержены ограничениям по запросам :
 * Вызываемая форма не должна каким-либо образом менять БД.Любая попытка из-
   менить поле,приводящая к изменению БД,запрещена и дает в результате сооб-
   щение об ошибке.Таким образом,в вызванной форме можно изменить поля толь-
   ко в управляющих блоках или поля "не БД".
 * Из команд SQL в триггере допускается только команда SELECT.Любая другая
   команда SQL приводит к завершению триггера по неисправимой ошибке и дает
   соответствующее сообщение.
 * Функция COMMIT (или [Commit]) не допускается,и результатом ее выполнения
   служит только сообщение об ошибке.
 * Функция CLRFRM (или [Clear Form/Rollback]) разрешена,однако,просто не
   имеет никакого эффекта.
 * Подсоединяемые программы пользователя не должны выполнять команды COMMIT
   WORK или ROLLBACK WORK.SQL*Forms не требует соблюдения данного ограниче-
   ния,однако результат выполнения указанных команд непредсказуем.

                                Команда #COPY
     Команда #COPY может использоваться в шаге триггера для копирования из
источника в приемник констант,значений полей,глобальных и системных перемен-
ных.Указание источника и приемника следует за ключевым словом "#COPY".Коман-
да #COPY - это единственный способ присвоить значение глобальной переменной.
Естественно,вы не можете использовать константы или системные переменные в
качестве приемника.
       Например,следующая команда присваивает значения содержимого поля
ORDERS.ORDERID переменной GLOBAL.ID:
       #COPY ORDERS.ORDERID GLOBAL.ID

     Пример применения команды #COPY,которая присваивает значения и исполь-
зует глобальные переменные в динамической системе получения вспомогательной
информации см.в разделе "Примеры триггеров SQL*Forms " в конце этой главы.

                                Команда #ERASE
     Команда #ERASE м.б. использована только для удаления значения глобаль-
ной переменной,имя которой следует за ключевым словом #ERASE.После удаления,
имя переменной становится неопределенным,и память,отведенная под эту переме-
нную,освобождается.
     Например,следующая команда удаляет переменную GLOBAL.ID,присвоение зна-
чения которой приведено выше:
                               #ERASE GLOBAL.ID
     Если присвоение значения глобальной переменной не выполнено (или она
уже удалена),команда #ERASE игнорируется.

                                Команда #HOST
     Команда #HOST позволяет выполнять команды ОС в шаге триггера.Вслед за
командой указывается командная строка (в кавычках) или имя поля (переменной),
содержащего командную строку.Выполнение текущей формы приостанавливается на
время выполнения системной команды.
     Например,следующая команда запускает SQL*Plus с указанием для него на-
бора выполняемых команд ("сценарий" команд) под именем ORDERRPT:
       #HOST 'SQLPLUS &ORDERRPT'

     Команда #HOST,работающая в одной ОС,возможно не будет работать в дру-
гой.Тем не менее,команды OPACLE такие,как SQLPLUS,переносимы и должны выпол-
няться в любой ОС,в которой работает ORACLE.

                 Шаг триггера,содержащий команду #HOST :
 * завершается успешно,если системная команда выполнена успешно или дала то-
   лько предупреждение
 * завершается неудачно,если системная команда возвращает код состояния,го-
   ворящий о серьезной ошибке
 * вызывает неисправимую ошибку (и аварийное завершение триггера) если сис-
   тема не может выполнить команду #HOST или дает код состояния неисправимой
   ошибки.

                               EПеременныеF
     Существуют 3 вида объектов SQL*Forms,которые можно использовать для
временного хранения переменных:
 * поля в текущей форме
 * глобальные переменные
 * системные переменные
     Вы можете использовать переменные этих 3 видов в любом месте команды
SQL*Forms,там,где можно использовать имя "[блок.]поле".Таблица 9-1 (см.выше
в этой главе) показывает несколько способов,которые обеспечивают использова-
ние переменных в командах #EXEMACRO,#COPY,#ERASE и #HOST.
     В дополнение вы можете использовать ссылки на переменную для рекурсив-
ного хранения имен переменных в других переменных.Это описано в конце дан-
ного раздела.

                          Глобальные переменные
     Глобальная переменная может хранить значения символьной строки любой
длины.Вы можете использовать глобальную переменную для хранения значений
данных вне блоков формы - особенно для передачи информации из одной формы в
другую когда применяете CALL и CALLQRY.

                 Имя глобальной переменной имеет вид :
       GLOBAL.имя_переменной
где :
    имя_переменной  - любое допустимое имя объекта ORACLE (см.приложение D).
     GLOBAL.имя_переменной никогда не интерпретируется как ссылка на блок по
имени GLOBAL.

     Вы не должны объявлять или определять глобальную переменную явно; она
начинает существовать при выполнении команды #COPY,присваивающей ей значе-
ние.Например,следующая команда присваивает значение поля ORDERS.ORDERID пе-
ременной GLOBAL.ID:
       #COPY ORDERS.ORDERID GLOBAL.ID

     Во время сеанса выполнения формы (RUN session) глобальная переменная
остается определенной (существующей) до тех пор,пока вы не используете кома-
нду #ERASE для ее удаления.
     Примеры использования глобальных переменных в системе динамического по-
лучения вспомогательной информации показаны в конце этой главы в разделе
"Примеры SQL*Forms триггеров".

                             Системные переменные
  За текущим положением курсора "следят" 3 системные переменные SQL*Forms :
 * SYSTEM.CURRENT_FORM содержит имя выполняющейся формы
 * SYSTEM.CURRENT_BLOCK содержит имя блока,в котором находится курсор
 * SYSTEM.CURRENT_FIELD содержит имя поля,в котором находится курсор
     "SYSTEM.имя_переменной" всегда интерпретируется как системная перемен-
ная,а не как ссылка на блок с названием SYSTEM.Допустимо использовать только
указанные (3) имени системных переменных.
     Значения системных переменных можно только считывать,но не присваивать.
Они полезны в триггере при необходимости точно знать местоположение курсора.
Примеры использования глобальных переменных в системе динамического получе-
ния вспомогательной информации показаны в конце этой главы в разделе "Приме-
ры SQL*Forms триггеров".

                            Ссылки на переменные
     В полях и глобальных переменных можно хранить не только значения дан-
ных,но также и имена других переменных.Обращение к таким переменным,имена
которых содержатся в других переменных,выполняется с использованием обозна-
чения "&переменная".Такое обращение называется ссылкой на переменную.
     Например,команда :
        #COPY ORDERS.STATUS GLOBAL.STATUS

копирует значение поля ORDERS.STATUS в глобальную переменную с именем GLO-
BAL.STATUS.Если ORDERS.STATUS содержит при этом строку "Нарушена минимальная
цена",то эта строка и присваивается переменной GLOBAL.STATUS.

     С другой стороны,команда :
        #COPY &ORDERS.STATUS GLOBAL.STATUS

рассматривает содержимое ORDERS.STATUS в качестве имени переменной,которая
содержит значение,подлежащее копированию в GLOBAL.STATUS.Если,при этом,в
ORDERS.STATUS хранится значение "SYSTEM.CURRENT_BLOCK",то SQL*Forms присва-
ивает имя текущего блока переменной GLOBAL.STATUS - но не строку
"SYSTEM.CURRENT_BLOCK".

                             Аналогично,команда :
        #COPY &ORDERS.STATUS &GLOBAL.STATUS

рассматривает содержимое ORDERS.STATUS как имя переменной,значение которой
м.б. скопировано, а содержимое GLOBAL.STATUS как имя переменной,в которую
происходит копирование.
     Вы можете организовать ссылку на переменную рекурсивно,с помощью вложе-
ний,включая столько уровней вложения,сколько пожелаете.Например,если
ORDERS.STATUS содержит значение &GLOBAL.MSG,SQL*Forms будет рассматривать
содержимое GLOBAL.MSG как имя переменной,значение которой нужно копировать,и
т.д..Имейте в виду,что SQL*Forms не имеет средств,позволяющих обнаружить
замкнутый цикл при рекурсивных ссылках на переменную.
     Аналогичный эффект при обращении к переменной достигается многократным
использованием знака "&",при этом обращение расшифровывается "изнутри-нару-
жу".Так,например,обращение &&ORDERS.STATUS интерпретируется как &(&ORDERS.
STATUS) - содержимое ORDERS.STATUS рассматривается как имя переменной,кото-
рая,в свою очередь,содержит имя другой переменной,значение которой подлежит
копированию.
     Ссылки на переменные полезны для переключения триггера на обработку ра-
зличных данных в различных ситуациях.Например,переменная SYSTEM.CURRENT_FIE-
LD дает имя текущего поля,а ссылка к переменной &SYSTEM.CURRENT_FIELD дает
содержимое текущего поля (при условии,что имя поля уникально в форме).Таким
образом,вы можете использовать такую ссылку для обработки в триггере значе-
ния текущего поля там,где это необходимо.
     Существует несколько способов использования ссылок на переменные в ко-
мандах SQL*Forms :
 * в качестве аргумента функции
 * в операторе CASE команды #EXEMACRO в качестве селектора (следующего за
   CASE) или выбора (следующего за WHEN)
 * в команде COPY в качестве источника или приемника
 * в команде #ERASE в качестве глобальной переменной,подлежащей удалению
 * в команде #HOST в качестве командной строки (при этом ссылка должна ука-
   зывать на имя переменной,содержащей строку,а не на строку непосредствен-
   но).
     В конечном счете (за исключением команды #HOST,см.выше,ссылка на пере-
менную должна указывать на желаемый объект.Например,ссылка на переменную в
команде #ERASE окончательно должна содержать имя глобальной переменной,вклю-
чая префикс GLOBAL.
     Ссылка вычисляется при фактическом выполнении команды триггера или фун-
кции,которые ее содержат.Например,если ключевой триггер содержит ссылку на
переменную,то значение этой ссылки всегда вычисляется заново каждый раз,ког-
да нажимается клавиша.

                      EПримеры SQL*Forms триггеровF
 1.При заполнении заказа в форме ORDENTRY оператор обычно вводит общую инфо-
   рмацию в блоке ORDERS и затем переходит непосредственно к LINEITEMS для
   ввода детализирующей информации.Следующий триггер переопределяет клавишу
   [Next Field] для последнего поля ввода в блоке ORDERS (ORDERSTOT) для пе-
   рехода к первому полю ввода в блоке LINEITEMS.

      Тип: KEY-NXTFLD для поля ORDERS.ORDERTOT

      #EXEMACRO NXTBLK

     Атрибуты: *Abort trigger when step fails
     Сообщение о неудаче: Нет возможности  перейти  к  блоку LINEITEMS
 2.При работе с блоками LINEITEMS оператор обычно вводит несколько элементов
   в строке.Следующий триггер переопределяет клавишу [Next Field] для после-
   днего поля ввода в блоке LINEITEMS (ITEMTOT) так,что происходит переход
   к следующей записи.

      Тип: KEY-NXTFLD для поля LINEITEMS.ITEMTOT

      #EXEMACRO NXTREC

     Атрибуты: *Abort trigger when step fails
     Сообщение о неудаче: Нет возможности перейти к следующей записи
 3.Поскольку ORDERS является моноблоком,клавиша [Next Set of Records] дубли-
   рует клавишу [Next Record].Следующий триггер применяет клавишу [Next Set
   of Record] к блоку LINEITEMS,даже если клавиша нажата при работе с блоком
   ORDERS.

      Тип: KEY-NXTSET для блока ORDERS

      #EXEMACRO NXTBLK; NXTSET; PRVBLK;

     Атрибуты: *Abort trigger when step fails
     Сообщение о неудаче: Нет возможности вывести на экран новый набор эле-
     ментов LINEITEMS
 4.Следующий триггер обобщает триггер (3) для применения ко всем блокам фор-
   мы ORDERNTRY :
      Тип: KEY-NXTFLD для всей формы

      Шаг 1: #COPY SYSTEM.CURRENT_BLOCK &GLOBAL.BLOCK

     Атрибуты: *Abort trigger when step fails

      Шаг 2: #EXEMACRO GOBLK ORDERS; NXTSET; GOBLK
             &GLOBAL.BLOCK;

     Атрибуты: *Abort trigger when step fails

      Заметим,что для возврата к начальному блоку,вы должны сохранить имя
      блока в переменной.
 5.Следующий триггер в блоке ORDERS выполняет триггер пользователя по имени
   GETCLIENT (см."Триггеры пользователя в главе 8) при любом изменении поля
   CLIENTID.GETCLIENT извлекает имя клиента и помещает его в поле ORDERS.
   NAME.

      Тип: Post-change триггер для поля ORDERS.CLIENTID

      #EXEMACRO EXETRG GETCLIENT;

     Атрибуты: *Abort trigger when step fails
 6.Следующий трехшаговый триггер обеспечивает соответствие записей,отобража-
   емых в блоке LINEITEMS (при введении новой записи в блок ORDERS),блоку
   ORDERS.(Для обеспе чения правильной координации блоков,аналогичные триг-
   геры должны применяться для всех функциональных клавиш,нажатие которых
   может привести к изменению записи текущего блока ORDERS).

      Тип: KEY-NXTREC для блока ORDERS

      Шаг 1: #EXEMACRO NXTREC;

     Атрибуты: *Abort trigger when step fails

      Шаг 2: SELECT 'X'
             FROM DUAL
             WHERE NVL (&ORDERS.ORDERID,-1)=NVL(
             &LINEITEMS.ORDERID,-1)

     Атрибуты: *Reverse return code
          *Abort trigger when step fails
          *Return succes when aborting trigger

      Шаг 3: #EXEMACRO NXTBLK;
             CASE ORDERS.ORDERID IS
             WHEN '' THEN CLRBLK;
             WHEN OTHERS THEN EXEQRY;
             END CASE; PRVBLK;

     Атрибуты: *Abort trigger when step fails

      Если оператор,работая с блоком ORDERS нажимает [Next Record],Шаг 1 пе-
      ремещает курсор к следующей записи.Затем Шаг 2 проверяет,соответствуют
      ли друг другу поля ORDERID в разных блоках.Если соответствуют,то шаг
      завершается неудачно и выполнение триггера прерывается,но завершение
      триггера считается успешным.При отсутствии соответствия,Шаг 3 осущест-
      вляет переход к блоку LINEITEMS.Затем,если поле ORDRES.ORDERID не со-
      держит значения,блок очищается,иначе выполняется запрос (для блока) и
      условием этого запроса является копирование поля ORDERID из блока
      ORDERS (как это установлено в окне SPECIFY VALIDATION).Таким образом,
      запрос выбирает (и копирует) только те записи,которые соответствуют
      текущему заказу.В любом случае,в итоге,макрокоманда возвращается к
      блоку ORDERS.
 7.Данный набор из 3 триггеров реализует систему получения динамической вс-
   помогательной информации,которая м.б. использована для всех имеющихся фо-
   рм.При этом требуется форма с именем HELPFORM,которая содержит единствен-
   ный блок,- HELP.Этот блок соответствует таблице HELP,содержащей столбцы
   для FORM (форма),BLOCK (блок),FIELD (поле) и MESSAGE (сообщение).

      Тип: KEY-HELP для всей формы
      (4 отдельных шага)

      #COPY SYSTEM.CURRENT_FIELD GLOBAL.FIELD
      #COPY SYSTEM.CURRENT_BLOCK GLOBAL.BLOCK
      #COPY SYSTEM.CURRENT_FORM GLOBAL.FORM
      #EXEMACRO CALL HELPFORM;

      Тип: KEY-OTHERS для всей формы HELPFORM

      #EXEMACRO EXEQRY; PAUSE; EXIT;

      Тип: Pre-query триггер для формы HELPFORM

      (3 отдельных шага)
      #COPY GLOBAL.FIELD HELP.FIELD
      #COPY GLOBAL.BLOCK HELP.BLOCK
      #COPY GLOBAL.FORM HELP.FORM

      Когда оператор нажимает [Help],макрокоманда KEY-HELP записывает теку-
щее поле,блок и форму в 3 глобальные переменные.Затем она приостанавливает
текущую форму и вызывает HELPFORM только для режима запроса.
      Когда высвечивается форма HELPFORM,ее текст подсказывает оператору о
необходимости нажать любую функциональную клавишу для получения вспомогате-
льной информации.Если оператор делает это,триггер KEY-OTHERS немедленно вы-
полняет запрос.Триггер pre-query копирует текущие значения поля,блока и фор-
мы из глобальных переменных в поля FIELD,BLOCK и FORM блока HELP.Это служит
в качестве условия запроса,по которому корректное сообщение,дающее вспомога-
тельную информацию,помещается в поле MESSAGE.
     По завершении запроса,функция PAUSE в триггере KEY-OTHERS приостанавли-
вает выполнение макрокоманды и выводит сообщение "Press any function key to
continue" ("нажми любую клавишу для продолжения").Когда оператор выполнит
это,функция EXIT возвращает управление вызывающей форме.

                   EКоманды подсоединяемых программF
                      Eпользователя в триггерахF
     Шаг триггера может на время выйти из SQL*Forms на программу,написанную
вами или другими пользователями.Вы можете использовать такие выходы к поль-
зователю для обработки информации в таблицах и полях формы,для вывода сооб-
щений и для выполнения такой обработки,которую нельзя осуществить средствами
SQL и SQL*Forms.Программы,выполняемые при выходе к пользователю (подсоединя-
емые программы пользователя),также могут выполнять вычисления и просматрива-
ть таблицы гораздо быстрее,чем команды SQL.
     На практике,поскольку подсоединяемые программы,как правило,сложнее на-
писать и внедрить,чем команды SQL и SQL*Forms,вы скорее всего будете исполь-
зовать их только в том случае,когда другие триггерные команды не дадут вам
требуемого результата :
 * при выполнении сложной проверки данных в поле
 * при выполнении сложных вычислений
 * при выполнении корректировок,которые инициируются значениями формы
 * при оптимизации характеристик прикладных программ.
     Так же,как и шаги триггера,подсоединяемые программы пользователя могут
завершаться успешно,неудачно или вызывать фатальные ошибки.Подсоединяемые
программы должны возвращать SQL*Forms код состояния,который идентифицирует
результат работы.

         EОбзор по написанию подсоединяемых программ пользователяF
     Этот раздел дает краткий обзор процесса написания и внедрения подсоеди-
няемых программ пользователя.Детальную информацию можно найти в приложении С
данного руководства.
     Вы можете написать подсоединяемые программы на таких языках,как C,
COBOL,FORTRAN,PL/I и Pascal.Не все из этих языков доступны в конкретных ОС;
смотри "ORACLE.Руководство по установке и использованию" для получения дета-
льной информации.
     Независимо от языков,используемых в ЭВМ,подсоединяемые программы поль-
зователя могут выполнять операции ORACLE с помощью включения в них команд на
языке SQL.Такие встроенные команды SQL имеют собственный синтаксис,построен-
ный на другой основе,чем синтаксис главных языков.
     Перед компиляцией подсоединяемой программы пользователя,вы должны "про-
пустить" ее через прекомпилятор (РСС),который переводит команды SQL в вызовы
функций главного языка.Затем вы можете использовать стандартный компилятор
главного языка для компиляции результата прекомпиляции.Если исходная прог-
рамма впоследствии будет изменена,то процесс прекомпиляции и компиляции м.б.
повторен заново.
     Для запуска формы,которая использует подсоединяемые программы пользова-
теля,вы должны связать объектный код с новой версией IAP (компонент SQL*
Forms,который запускает форму).
     Для реализации подсоединяемых программ пользователя придерживайтесь
следующего общего алгоритма (детально это описано в приложении С) :
 1.Используйте утилиту GENXTB для добавления элемента,объявляющего новую по-
   дсоединяемую программу пользователя для таблицы IAPXTB модуля IAPXIT (ко-
   мпонент IAP).
 2.Напишите подсоединяемую программу на выбранном вами (главном) языке.
 3.Запустите PCC с указанием исходного файла подсоединяемой программы.
 4.Запустите компилятор с выбранного главного языка с указанием файла,созда-
   нного PCC.
 5.Создайте новую версию IAP с помощью совместной компоновки стандартных мо-
   дулей IAP,модифицированного модуля IAPXTB и новых модулей подсоединяемой
   программы пользователя.
 6.Определите в форме шаг триггера,подключающий подсоединяемую программу.
 7.Проверьте и отладьте подсоединяемую программу.Каждый раз,когда вы произ-
   водите изменения,возвращайтесь к шагу 3.
 8.После того,как подсоединяемая программа готова,проинструктируйте операто-
   ров,как использовать новую версию IAP при работе с формой (если новая ве-
   рсия IAP заменяет стандартную,в этом нет необходимости).

          EВызов подсоединяемых программ пользователя из триггераF
     После того,как вы написали,отладили,прекомпилировали,скомпилировали и
скомпоновали подсоединяемую программу,вызвать ее из шага триггера достаточно
легко.Достаточно поместить ее имя в шаг триггера,указав перед именем знак #,
а после имени те параметры,которые должна воспринимать программа :
        #имя_программы параметры

   Удостоверьтесь в том,что вы определили сообщение об ошибке в окне TRIGGER
STEP.
     Например,шаг триггера:
        #VALIDATE 10 25 A
подключает подсоединяемую программу по имени VALIDATE с тремя параметрами.

        EПередача значений подсоединяемым программам пользователяF
     При подключении подсоединяемой программы триггер передает ей :
 * вызывающую строку и ее длину
 * сообщение о неудачном завершении (и его длину)
 * значение флага,указывающего,в каком режиме был вызван триггер: в обычном
   или режиме запроса (подсоединяемая программа может выполнять различные
   функции в зависимости от значения этого флага)
     В подсоединяемых программах вы также можете использовать значения пере-
менных SQL*Forms :
 * Допускается использовать ссылку " [блок.]поле ",глобальные переменные и
   системные переменные непосредственно в операторах EXEC IAF GET и PUT.
          Например,операторы:
           EXEC IAF GET ORDERS.ORDERID INTO :val
           EXEC IAF GET GLOBAL.ID INTO :val
           EXEC IAF GET SYSTEM.CURRENT_FIELD INTO :val

   присваивают :val значение поля ORDER.ORDERID,значение глобальной перемен-
   ной GLOBAL.ID и имя текущего поля соответственно.
 * Хотя прекомпилятор не воспринимает амперсанд(&) в обращении к переменной,
   таком,как &[блок.]поле, вы можете использовать этот синтаксис в прекомпи-
   лируемых переменных операторов EXEC IAF GET и PUT.Например,если перемен-
   ная прекомпиляции :name содержит значение &ONE.NAME,то оператор :
           EXEC IAF GET :name INTO :val

   присваивает переменной :val значение поля или глобальной переменной,имя
   которой содержится в поле ONE.NAME.

                   EЗамечания по отладке триггеровF
     В дополнение к общему совету по тестированию и отладке форм в главе 4,
укажем несколько специфичных моментов для триггеров :
 * При неудачном завершении триггера по ошибке в операторе SQL или в макро-
   команде шага,нажмите [Display Error] для отображения ошибочного оператора.
 * Иногда ошибки приводят к невозможности успешного завершения шага тригге-
   ра.Если это шаг post-change или post-field триггера,то вы "застрянете" в
   поле и не будет возможности ввести какое-либо значение,чтобы курсор поки-
   нул данное поле.Из этой ловушки можно,как правило,"выбраться" нажатием
   [Exit/Cancel],что приведет вас к возврату в окно CHOOSE FORM из любого
   поля.Если [Exit/Cancel] не работает,попробуйте [Clear Record],затем [Cle-
   ar Block],затем [Exit/Cancel].

+                         EГЛАВАF E10F
                      EКомпоненты SQL*FormsF
     SQL*Forms состоит из нескольких отдельных компонентов,объединенных ок-
ном CHOOSE FORM.Несмотря на то,что более удобный путь определения и выполне-
ния форм осуществляется через SQL*Forms,иногда полезно осуществлять и запуск
компонентов по отдельности.Например,вы можете использовать компоненты SQL*
Forms для перевода формы из одного формата в другой.
     В этой главе для обсуждения будут предложены следующие вопросы:
 * о форматировании хранящейся формы
 * о взаимосвязи между системами и устройствами
 * о функциях всех компонентов SQL*Forms
 * о том,как выполнить каждый компонент.

                        EФорматы хранения формF
     В SQL*Forms формы хранятся в 3 различных форматах:
 * Формат БД (в нескольких таблицах БД ORACLE).Это основной формат,использу-
   емый,когда форма выбрана для модификации или когда какое-либо действие
   выбирается из окна FILE.
 * Формат FRM (в виде двоичного файла,обычно с расширением FRM).Это формат,в
   котором форма создается при генерации (GENERATE) и выполняется (RUN).
 * Формат INP (текстовый файл,обычно с расширением INP).Это промежуточный фо-
   рмат,использующийся при генерации (GENERATE) файлов с расширением FRM.Кро-
   ме того,если у вас имеется файл с расширением INP,созданный в другой вер-
   сии SQL*Forms (или с другими параметрами установки),его можно загрузить
   (LOAD) непосредственно в SQL*Fodms (INP был основным форматом хранения в
   версиях SQL*Forms,предшествующих версии 1.0,когда формы не хранились в БД).
     Компоненты SQL*Forms можно ипользовать для перевода формы из одного фо-
   рмата в другой,как показано на рисунке 10-1.
          Ъ----------------ї            Ъ----------------ї
          Г----------------ґ            Г----------------ґ
          і                і      IAC   і                і
          і  .INP файл     і<---------->і  База данных   і
          А----------------Щ            А----------------Щ
              ^
              і IAG
              v
          Ъ----------------ї
          Г----------------ґ
          і  .FRM файл     і
          А----------------Щ
        Рис.10-1.Форматы форм и компоненты.

                   EСоглашения по наименованиям файловF
     SQL*Forms использует имя формы как основу для имен файлов с расширения-
ми INP и FRM.INP и FRM обычно добавляются как суффиксы к именам форм (хотя
это зависит от ОС).Таким образом,когда выбирается имя для формы,нужно удос-
товериться в правильности написания базовых имен файлов (без суффиксов) по
правилам вашей ОС.

                       EКомпоненты SQL*FormsF
     Компоненты SQL*Forms включают:
 * интерактивный построитель программ SQL*Forms (называется также IAD),кото-
   рый создает или модифицирует форму в БД.Этот компонент является главным и
   может вызывать все остальные.Он также выполняется,когда вы выбираете
   CREATE или MODIFY из окне CHOOSE FORM.
 * интерактивный преобразователь программ SQL*Forms (IAC),который преобразу-
   ет форму из формата БД в формат INP и наоборот.Он выполняется,когда вы
   выбираете GENERATE или LOAD в окне CHOOSE FORM.
 * интерактивный генератор программ (IAG),который cчитывает файлы с расшире-
   нием INP и преобразует их в файлы с расширением FRM.Он выполняется после
   IAC,когда вы выбираете GENERATE в окне CHOOSE FORM.
 * RUNFORM (IAP),интерактивный процессор программ,который считывает форму из
   файла FRM и выполняет ее.Этот компонент выполняется,когда вы выбираете
   RUN в окне CHOOSE FORM.

                   EПереносимость между системамиF
     Форматы БД и файлов с расширением INP одинаковы для всех типов компью-
теров,поддерживающих SQL*Forms; форматы же файлов с расширением FRM не оди-
наковы.Таким образом,не следует пытаться переносить формы с одного типа ком-
пьютера на другой,используя формат FRM.Вместо этого скопируйте файл с расши-
рением INP и загрузите его или выполните процедуру IAC с опцией -i.
     В качестве альтернативного метода можно использовать метод экспорта/им-
порта.Для экспорта таблиц,содержащих формы одной системной БД,можно исполь-
зовать утилиту ORACLE "EXPORT",а для импорта их в другие БД - утилиту "IMPO-
RT".Процедуры "EXPORT" и "IMPORT" рассмотрены в "Утиллиты ORACLE.Руководство
пользователя"".
     В любом случае можно пересоздать файл FRM при помощи регенерации формы
или при выполнении процедуры IAG.

             EПереносимость между устройствами отображенияF
     В формате БД линии и рамки хранятся таким образом,что их отображение не
зависит от устройства.С другой стороны,форматы INP и FRM сохраняют линии и
рамки как последовательности текстовых символов.Поскольку для построения ли-
ний и рамок на различных устройствах используются различные символы,эти фор-
маты для форм,содержащих линии и рамки,являются зависящими от устройства.
     В связи с этим возникают проблемы при конструировании формы,которая до-
лжна выполняться :
 * на устройстве отображения,которое отличается от установленного по умолча-
   нию,либо
 * на двух или более типах видеотерминалов.
     Обычным путем для устранения таких проблем является использование SQL*
Forms для создания формы в формате БД,затем выполняются процедуры IAC и IAG,
чтобы отдельно сгенерировать файл INP и файл FRM для каждого типа видеотер-
минала.Каждый оператор должен получить инструкцию по запуску файла FRM,сге-
нерированного для конкретного устройства,на котором этот оператор работает.
     Графические символы (уникальные символы для определенных типов термина-
лов) во всех 3 форматах являются зависящими от устройства.Если в форме соде-
ржатся такие символы,необходимо для каждого видеотерминала создать отдельную
версию формы,которая сможет на нем выполняться.В этом случае необходимо за-
пускать SQL*Forms отдельно для каждого устройства.
     Например,предположим,что форма с именем SUBSCRIBE д.б. выполнена на 4
различных устройствах A,B,C и D.Для этого необходимо:
 1.Создать форму для устройства A при помощи запуска SQL*Forms на этом уст-
   ройстве.
 2.Использовать действие SAVE AS в окне FILE,чтобы создать копию формы для
   одного из других типов устройств.Для удобства рекомендуется включать имя
   устройства в имя формы.Например,SUBSCRIBE3270  для 3270-дисплеев.
 3.Выйти из SQL*Forms,переключиться на видеотерминал B и снова запустить
   SQL*Forms.Использовать этот терминал для модификации копии формы,сделан-
   ной во втором шаге,путем замены графических символов на каждой странице.
   Другие элементы формы модифицировать необязательно.
 4.Повторить шаги 2 и 3 для видеотерминалов C и D.
 5.Обучить оператора использованию копии формы,модифицированной для работы
   на его устройстве отображения.

              ESQL*Forms,интерактивный построитель программF
     IAD (Interactive Application Designer) является главным компонентом,по-
дключающим все остальные.Добавим,что этот компонент создает и модифицирует
форму.Он читает и записывает ее в формате БД.
     Запустите SQL*Forms с опциями в командной строке,когда вам необходимо
определить видеотерминал,отличающийся от установленного по умолчанию.

                          EЗапуск SQL*FormsF
      Чтобы запустить SQL*Forms,наберите после подсказки вашей ОС следующую
команду:
            SQLFORMS [опции] [имя_формы] [имя_пользователя/пароль]
     "имя_формы" - имя формы,с которой вы хотите работать.
     SQL*Forms выбирает форму (или создает ее,если ранее она не существовала
в БД) и высвечивает окно CHOOSE BLOCK.Если этот параметр опущен,вместо этого
окна на экране появляется окно CHOOSE FORM.
     "имя_пользователя" и "пароль" - имя пользователя и пароль действитель-
ные для ORACLE.Если опустить эти параметры,
     SQL*Forms высветит окно регистрации,изображенное на рисунке 2-1.
     Вы можете использовать любую из перечисленных ниже опций:

     Имя    Синтаксис                Описание
     ----------------------------------------------------------Д
     CRT    -с crt   Используется указанный файл crt определений (описанный
                     в " Руководстве администратора БД ORACLE").Если эта оп-
                     ция опущена,то предполагается устройство по умолчанию.
     Эхо    -e файл  Записывает в "Эхо" файл последова-
     (Echo)          тельность нажимаемых клавиш.
     Читать -r файл  Считывает и выполняет записанную в
     (Read)          файле "Эхо" последовательность нажатых клавиш.Когда фа-
                     йл закончится,ввод осуществляется с терминала.
     Строка   -s     Исчезает установленная в нижней части
     состояний       экрана строка состояний.
     (Status
     Line)
     Записать  -w файл  Записывает выходную информацию в вы-
     (Write)            водной файл.
               -w+файл  Записывает выходную информацию одновременно в вывод-
                        ной файл и на терминал.
     Вы можете вводить символы опций как на нижнем,так и на верхнем регист-
рах.Для получения помощи необходимо  набрать следующее:
                                                        SQLFORMS - ?

              EIAC,интерактивный преобразователь программF
     IAC (Interactive Application Converter) преобразует форму из формата БД
в формат INP и наоборот.
     Для того,чтобы преобразовать файл INP,сгенерированный в другой версии
SQL*Forms или в версии с другими параметрами установки,в формат БД,запустите
IAC отдельно,в качестве альтернативы LOAD.Для того,чтобы произвести обратные
преобразования,запустите IAC,как альтернативу GENERATE.

                             EЗапуск IACF
    Чтобы запустить IAC,наберите после подсказки вашей ОС следующую команду:
      IAC [опции] inp_файл имя_формы [имя_пользователя/пароль]

     "inp_файл" - имя файла INP (без расширения .INP),который вы хотите соз-
дать (или преобразовать,если будете использовать опцию -i ).
     "имя_формы" - имя формы,которую вы хотите преобразовать(или создать,ес-
ли будете использовать опцию -i).
     "имя_пользователя" и "пароль" - имя пользователя и пароль,действитель-
ные для ORACLE.Если опустить эти параметры,SQL*Forms высветит окно регистра-
ции,изображенное на рисунке 2-1.

     Вы можете использовать любую из перечисленных ниже опций:

     Имя    Синтаксис                  Описание
     ----------------------------------------------------------Д
     CRT     -с crt  Используется указанный файл crt определений (описанный
                     в "Руководстве администратора БД ORACLE".Если эта опция
                     опущена,вашему видеотерминалу присваиваются установки
                     по умолчанию.Опция crt д.б. указана в том случае,если
                     форма содержит линии,рамки или графические символы и
                     будет выполняться не на том видеотерминале,который ус-
                     тановлен по умолчанию.
     Удалить   -d    Удаляет форму с именем "имя_формы" из БД.При этом имя
    (Delete)         "inp_файла" м.б. указано,хотя и проигнорируется.Все
                     другие опции также проигнорируются.
     Вставить   -i    Вставляет файл INP в БД.Если эта опция опущена,проис-
     (Insert)        ходит преобразование из формата БД в формат файла INP.
     Подавить   -s    Не высвечивает заголовок программы
     вывод           или   подсказки  "Reading..."  и
     сообщений       "Writing...".
     (Suppres
     Feedback)
Вы можете вводить символы опций как на нижнем,так и на верхнем регистрах.Для
получения помощи необходимо набрать следующее:
                                                   IAC - ?

                 EIAG,интерактивный генератор программF
     IAG (Interactive Application Generator) создает файл FRM.Он может также
создавать или модифицировать файл INP в зависимости от того,существует ли
этот файл,и,от того,какие опции вы указали:
 * Если файл INP не существует,IAG ведет с вами диалог типа "вопрос-ответ"
   для того,чтобы определить форму.Затем он создает файл INP,а также файл
   FRM.
 * Если файл INP существует,но не определены ни опция -о,ни -b,IAG считывает
   определение формы из файла и ведет диалог типа "вопрос-ответ",с помощью
   которого вы можете модифицироовать эту форму.Затем он вносит все произве-
   денные изменения в файл INP и создает файл FRM.
 * Если файл INP существует и определена одна из опций (либо -о,либо -b),IAG
   просто считывает файл INP и создает новый файл FRM.При этом диалог типа
   "вопрос-ответ" не происходит и не создается новый файл INP.

     Файл INP,как правило,состоит из двух частей :
 * текста вопросов,задаваемых IAG в ходе диалога,во время которого создается
   форма
 * текста ваших ответов на задаваемые вопросы.Для того,чтобы создать файл
   FRM,выполните IAG как отдельную программу после запуска SQL*Forms и IAC.

                              EЗапуск IAGF
   Чтобы запустить IAG,наберите после подсказки вашей ОС следующую команду:
              IAG inp_файл [ опции ]

     "inp_файл" - имя файла INP (без расширения),который вы хотите преобра-
зовать или создать.IAG создает файл FRM с тем же именем (отличающимся лишь
расширением ).
     Любая из опций м.б. использована в различных комбинациях и в любой пос-
ледовательности.Если используется более,чем одна опция,перед ними ставится
только один дефис и между ними не м.б. пробела.

     Имя    Синтаксис                 Описание
     ----------------------------------------------------------Д
     Краткий   -b    Имеет то же действие,что и совместное
     (Brief)         использование опций "Отмена сообще-
                     ний"(-t) и "Только FRM"(-о).
     Только FRM -o    Запрещает создание нового файла INP и
     (Only           подавляет диалог."inp_файл" уже дол-
     FRM)            жен существовать.
     Отмена -s       Пропускает вопросы диалога для но-
     диалога         вого  файла INP; записывает только
     (Suppres        ответы.Это не влияет на использова-
     Dialogue)       ние файла INP,но его размер существенно уменьшается.
     Отмена    -t    Не высвечивает диалога,при помощи ко-
     сообщений       торого создавалась форма,который,в
     (Suppres        противном случае,IAG представляет во
     Talk)           время генерации файла FRM.
Вы можете вводить символы опций как на нижнем,так и на верхнем регистрах.Для
получения помощи необходимо набрать следующее:
                                                   IAG - ?

                     ERUNFORM,процессор формF
     RUNFORM (или IAP),считывает форму из файла FRM и выполняет ее.
     RUNFORM используется как отдельная программа для:
 * выполнения формы на устройстве отображения,отличном от того,который уста-
   новлен по умолчанию
 * выполнения формы,вызывающей подсоединяемые программы пользователя,не свя-
   занные со стандартной версией RUNFORM (вы должны использовать пользовате-
   льскую версию RUNFORM,содержащую эти программы)
 * предотвращения создания или модификации своих собственных форм оператора-
   ми (другие компоненты SQL*Forms для RUNFORM не допустимы).

                          EЗапуск RUNFORMF
Чтобы запустить RUNFORM,наберите после подсказки вашей ОС следующую команду:
      RUNFORM [ опции ] имя_формы [имя_пользователя/пароль]

     "имя_формы" - имя формы,которую вы хотите выполнить.
     "имя_пользователя" и "пароль" - имя пользователя и пароль,действитель-
ные для ORACLE.Если опустить эти параметры,SQL*Forms высветит окно регистра-
ции,изображенное на рисунке 2-1.
     Вы можете использовать любую из перечисленных ниже опций,многие из ко-
торых дублируют действие элементов окна SPECIFY RUN OPTIONS.Фактически,запу-
ск RUNFORM без опций имеет тот же эффект,что и выбор всех значений по умол-
чанию в этом окне.

     Имя    Синтаксис                      Описание
     ----------------------------------------------------------Д
     Запись в  -b     Экономит память(но замедляет обработ-
     буфер            ку) путем буферизации выбираемых за-
     (Buffer          писей в файл,а не в память.Дей-
     Records)         ствие этой опции аналогично действию ключа "Buffer
                      records" в окне SPECIFY RUN OPTIONS.
     CRT    -с crt    Используется указанный файл crt определений (описанный
                      в "Руководстве администратора БД ORACLE").Если эта оп-
                      ция опущена,вашему видеотерминалу присваиваются уста-
                      новки по умолчанию.
     Режим   -d       Высвечивает текущие сообщения о вы-
     отладки           полнении триггеров и о других состоя-
     (Debug           ниях формы.Его действие аналогично
     Mode)            действию ключа "Debug mode" в окне SPECIFY RUN OPTIONS.
     Эхо    -e файл   Записывает в "Эхо" файл  последова-
     (Echo)           тельность нажимаемых клавиш.
     Отмена   -l      Отменяет автоматическую регистрацию.
     регистрации      Имя пользователя и пароль не указы-
     (Login           ваются.
     Disable)
     Меню    -m       Начинает выполнение формы с высвечива-
     (Menu)           ния меню блоков,в котором оператор может осуществлять
                      выбор.Действие этой опции аналогично действию ключа
                     "Display menu" в окне SPECIFY RUN OPTIONS.
     Не опти-   -o    Экономит память(но замедляет обработ-
     мизировать       ку) при помощи назначения отдельных
     SQL              курсоров только тем шагам триггеров,
     (Don't           которые  вы  специально  обозначи-
     Optimize         ли  (вместо назначения всем шагам
     SQL)             триггеров).Действие этой опции аналогично действию
                      ключа "Optimize SQL processing" в окне SPECIFY RUN
                      OPTIONS.
     Режим    -q      Отключает сигнал во время автоперехо-
     (Quiet           да,вывода помощи и некоторых сообще-
     Mode)            ний.Действие этой опции аналогично
                      действию ключа "Quiet mode" в окне SPECIFY RUN OPTIONS.
     Читать   -r файл Читает и выполняет записанную в "Эхо"
     (Read)           файл последовательность нажатых клавиш.По окончании
                      выполнения файла ввод осуществляется с терминала.
     Статистика  -s   Высвечивает количество курсоров  к
     (Statistics)     концу сеанса работы.Действие этой опции аналогично де-
                      йствию ключа "Statistics" в окне SPECIFY RUN OPTIONS.
     Не оптими-  -t    Экономит память(но замедляет обработ-
     зировать         ку) при помощи назначения отдельных
     процесс          курсоров только операторам запроса
     транзакции       Select (вместо назначения и другим
     (Don't           операторам SQL).Действие этой опции
     Optimize         аналогично действию ключа "Optimize
     Transaction      transaction" в окне  SPECIFY  RUN
     Processing)      OPTIONS.
     Записать -w файл  Записывает выходную информацию в вы-
     (Write)          водной файл.
              -w+файл  Отображает выходную информацию одновременно в вывод-
                      ной файл и на терминал.
Вы можете вводить символы опций как на нижнем,так и на верхнем регистрах.Для
получения помощи необходимо набрать следующее:
                                                    RUNFORM - ?

+                       EПриложениеF EАF
                      EСообщения об ОшибкахF
EIAD-1 : Field too large for this form (Поле слишком велико для этой формы)F
 Причина : Выбранное поле или область являются слишком большими для копиро-
           вания или перемещения в новое местоположение.Поле или область во
           временном "paste"-буфере слишком велики для размещения в новом
           месте.
 Действие: Подобрать новое местоположение,либо отменить сделанный выбор,либо
           отказаться от функции CUT.
 EIAD-2 : This field will overlap another field (Это поле будет перекрыто
           другим полем)F
 Причина : Вы пытаетесь создать поле или изменить его размер таким образом,
           что оно будет перекрыто другим полем.
           Вы  пытаетесь перемещать,копировать или вставлять поле или облас-
           ть в новое место,где оно будет перекрыто другим полем.
 Действие: Изменить размер или позицию поля,чтобы избежать перекрытия.
EIAD-3 : Your form is too large for your CRT screen (Форма слишком велика
           для вашего дисплея)F
 Причина : Форма для вашего текущего видеотерминала слишком велика.
 Действие: Изменить размер формы или использовать другое устройство отобра-
           жения с большим экраном.
 EIAD-4 : Cursor is outside the current form (Курсор находится за пределами
           текущей формы)F
 Причина : Курсор переместился за пределы формы,которую вы определили в эк-
           ранном построителе форм.
 Действие: Вернуть курсор обратно в форму.
 EIAD-5 : You cannot select more than twice at the same time
           (Вы не можете осуществить более двух выборов одновременно)F
 Причина : Вы нажали [Select] не менее трех раз подряд.
 Действие: Нажать функциональную клавишу,которая обращается к выбранным эле-
           ментам,после нажатия [Select] не более двух раз.
 EIAD-6 : You pressed an undefined function key ( Вы нажали
           неопределенную функциональную клавишу)F
 Причина : Вы нажали функциональную клавишу,которая в экранном построителе
           форм не имеет соответствующей ей функции.
 Действие: Действий не требуется.Чтобы быть уверенным в использовании той
           или иной функциональной клавиши,необходимо обратиться к карте
           клавиатуры экранного построителя форм.
 EIAD-7 : You cannot select partial field; field is split across selected
           boundary (Вы не можете выбирать часть поля; выбранная граница ра-
           зрывает поле)F
 Причина : Вы пытаетесь выбрать область,которая включает лишь часть поля (а
           не полностью поле ).
 Действие: Действий не требуется; выбрать область,которая не рассекает ника-
           кого поля.
 EIAD-8 : Field cannot span line boundary (Поле не должно пересекать грани-
           цу линии)F
 Причина : Вы пытаетесь создать поле или изменить его размер таким образом,
           что оно пересекает линии (рамки).
 Действие: Действий не требуется.
 EIAD-9 : Nothing has been selected (Ничего не было выбрано)F
 Причина : Вы запрашиваете операцию (например,[Create field]),которой требу-
           ется одно или более предварительных [Select],без предварительного
           нажатия клавиши [Select].
 Действие: Один или 2 раза выполнить [Select],как требуется для запрашивае-
           мой вами операции; затем повторить операцию.
EIAD-10 : Yoy can resize only one field at a time (Одновременно вы можете
           изменить размер только одного поля)F
 Причина : Вы пытаетесь изменить размер ([Resize]) области,которая не содер-
           жит поля или включает более,чем одно поле.
 Действие: Отменить выбор; изменить размер поля при помощи выбора этого поля
           и нового указателя конца поля,а затем нажатия [Resize].
EIAD-11 : You can expand field only to the right (Вы можете расширить поле
           только вправо)F
 Причина : Вы пытаетесь изменить размер поля,перемещая его начало влево.
 Действие: Изменить размер поля,перемещая его правую границу вправо.Чтобы
           расширить поле влево,необходимо переместить влево целое поле,а
           затем сдвинуть вправо его правую границу.
EIAD-12 : You can expand screen only to the right or down
           (Вы можете расширить экран только вправо или вниз)F
 Причина : Это сообщение является результатом внутренней ошибки SQL*Forms.
 Действие: Необходимо сообщить администратору БД или представителю корпора-
           ции ORACLE.
EIAD-13 : Resizing your form would split or drop at least one field (Изме-
           няя размер формы вы можете разорвать или удалить по крайней мере
           одно поле)F
 Причина : Это сообщение является результатом внутренней ошибки SQL*Forms.
 Действие: Необходимо сообщить администратору БД или представителю корпора-
           ции ORACLE.
EIAD-14 : You cannot resize boilerplate text (Вы не можете
           изменить размер константного текста)F
 Причина : Вы не выбрали поля для изменения его размера.Размеры областей,от-
           личных от полей,не м.б. изменены.
 Действие: Изменить размер поля при помощи выбора этого поля и нового указа-
           теля конца поля,а затем нажатия [Resize].Измените область,отлич-
           ную от поля с помощью,ее перемещения или редактирования.
EIAD-15 : Nothing to undo (Нечего отменять)F
Причина: Вы нажимаете [Undo],но отсутствует операция,которую можно отменить.
 Действие: Действий не требуется.
EIAD-16 : Yoy can define only one field at a time ( За одно действие вы мо-
           жете определить только одно поле)F
 Причина : Вы выбрали область,которая не содержит полей
           или включает более,чем одно поле.
 Действие: Отменить выбор.Чтобы определить поле,помести-
           те курсор в это поле и нажмите [Define].
EIAD-17 : Operation is not applicable for a block (Операция
            для блока неприменима)F
 Причина : После того,как была нажата клавиша [Select block],вы пытаетесь
           выполнить операцию,которая является неприменимой для блока.
 Действие: Отменить [Select block] или запросить операцию (такую,как [Defi-
           ne]),которая является применимой для блока.
EIAD-18 : Block is already selected (Блок уже выбран)
 Причина : Вы нажимаете [Select block] подряд более,чем один раз.
 Действие: Действий не требуется.
 EIAD-19 : You cannot select a block whil select active (Вы не можете выби-
           рать блок пока действует предыдущий выбор)
 Причина : Вы нажимаете [Select block] после того,как
           произвели выборы через [Select].
 Действие: Действий не требуется.
 EIAD-20 : Yoy cannot modify fields that do not belong to the current block
            (Вы не можете модифицировать поля,которые не принадлежат текуще-
           му блоку)F
 Причина : Вы пытаетесь модифицировать поле,не принадлежащее текущему блоку.
 Действие: Отмените нежелательный выбор (если он есть).Функциональные клави-
           ши [Next field] и [Previous field] позволят вам перемещаться по
           всем полям,принадлежащим текущему блоку на этой странице.
EIAD-21 : Nothing to paste (Нечего вставлять)F
 Причина : Вы нажимаете [Paste] в то время,как буфер пуст.
 Действие: Действий не требуется.
 EIAD-22 : Cannot open file with this name (Файл с таким именем не м.б.
           открыт)F
 Причина : Вы указали неправильное имя файла или файла с таким названием не
           существует.
 Действие: Указать правильное имя файла.
EIAD-26 : Cursor is outside the current window (Курсор нахо-
           дится за пределами текущего окна)F
 Причина : Вы переместили курсор за пределы текущего окна.
 Действие: Необходимо переместить курсор в нужное место в текущем окне и
           повторить операцию.
EIAD-27 : Cursor is not positioned on a valid choice a window (Курсор не
           спозиционирован на необходимом выборе в окне)F
 Причина : Вы выполняете операцию,которая обращается к опции окна,но курсор
           не находится на этой опции или непосредственно перед ней.
 Действие: Переместить курсор к опции и повторить операцию.
EIAD-30 : Internal error: Definer Forms are invalid (Внут-
           ренняя ошибка: ошибка определителя форм)F
 Причина : Это внутренняя ошибка.
 Действие: Необходимо сообщить администратору БД или представителю корпора-
           ции ORACLE.
EIAD-31 : Form name is invalid (Имя формы является ошибочным)F
 Причина : Вы определили недопустимое имя формы.
 Действие: Указать правильное имя формы и повторить операцию.
EIAD-32 : Form with this name already exists (Форма с таким
           именем уже существует)F
 Причина : Вы пытаетесь создать форму с именем,которое уже используется.
 Действие: Необходимо выбрать другое имя или переименовать форму,из-за имени
           которой возникла эта ошибка.
EIAD-33 : Form with this name does not exist (Формы с таким
           именем не существует)F
 Причина : Вы пытаетесь обратиться к несуществующей форме.
 Действие: Ввести  имя  существующей формы.Перейти в окно LIST FORMS,чтобы
           посмотреть имена имеющихся форм.
EIAD-34 : Form name must be entered ( Д.б. введено имя формы )F
 Причина : Вы пытаетесь выполнить операцию,которой требуется имя формы,но
           оно не введено или не выбрано вами.
 Действие: Ввести или выбрать имя формы и повторить операцию.
EIAD-35 : Block name is invalid (Имя блока является ошибочным)F
 Причина : Вы определили недопустимое имя блока.
 Действие: Указать правильное имя блока и повторить операцию.
EIAD-36 : Block with this name already exists (Блок с таким именем уже
           существует)F
 Причина : Вы пытаетесь создать блок с именем,которое
           уже используется в этой форме.
 Действие: Выбрать другое имя для блока или переименовать тот блок,из-за
           имени которого возникла эта ошибка.
EIAD-37 : Block with this name does not exist (Блок с таким
            именем не существует)F
 Причина : Вы пытаетвсь обратиться к несуществующему блоку.
 Действие: Ввести имя существующего блока.Перейти в окно LIST BLOCKS,чтобы
           посмотреть список имен существующих блоков.
EIAD-38 : Page number is invalid ( Ошибочный N страницы )F
 Причина : Вы ввели N страницы,который является недопустимым или выходит за
           пределы допустимого в SQL*Forms диапазона.
 Действие: Ввести допустимый N страницы.
EIAD-39 : Block name must be entered (Д.б. введено имя блока )F
 Причина : Вы пытаетесь выполнить операцию,для выполнения которой требуется
           имя блока,но оно не введено или не выбрано вами.
 Действие: Ввести или выбрать имя блока и повторить операцию.
EIAD-40 : Block sequence number is invalid (Порядковый N блока является
           недопустимым)F
 Причина : Вы ввели порядковый N блока,который является недопустимым или
           выходит за пределы допустимого в SQL*Forms диапазона.
 Действие: Ввести допустимый порядковый N блока.
EIAD-41 : This table name is invalid ( Ошибка в имени таблицы )F
 Причина : Вы указали недопустимое имя таблицы.Допустимое имя таблицы должно
           удовлетворять правилам наименования объектов БД ORACLE.
 Действие: Указать правильное имя таблицы и повторить операцию.
EIAD-42 : Table or view with this name does not exist (Таблицы или экранной
           формы с таким именем не существует)F
 Причина : Вы пытаетесь обратиться к таблице или экранной форме,которой не
           существует.
 Действие: Введите имя существующей таблицы или экранной формы.
EIAD-43 : You deleted a block that is being referred to (Вы удаляете блок,к
           которому в настоящее время идет обращение)F
 Причина : Вы удаляете блок,к которому идет обращение и из другого места в
           текущей форме (например,при помощи спецификации "List of possible
           values" в определении поля).
 Действие: Изменить форму так,чтобы она не обращалась к удаляемому блоку.
EIAD-44 :SQL sequence number is invalid (Ошибка в порядковом номере SQL )F
 Причина : В шаге триггера вы вводите порядковый N шага,который является не-
           допустимым числом или выходит за пределы допустимого в SQL*Forms
           диапазона.
 Действие: Ввести допустимый порядковый N шага.
EIAD-45 : Syntax error in SQL  statement (Синтаксическая
           ошибка в операторе SQL)F
 Причина : Команда SQL,которую вы только что ввели или отредактировали,
           содержит синтаксическую ошибку.
 Действие: Ввести правильную команду.Обратитесь к "SQL*Plus.Руководство по-
           льзователя" для получения информации о синтаксисе команд SQL.
EIAD-46 : Field does not exist in specified block (Такого
            поля в указанном блоке не существует)F
 Причина : Вы вводите указатель поля,который обращается к комбинации [блок.
           поле],которой не существует.
 Действие: Ввести правильную комбинацию имен блока и поля.
EIAD-47 :Number of displyed rows cannot exceed number of buffered rows (Чи-
         сло выводимых строк не может превышать число буферированных строк)F
 Причина : В окне SPECIFY BLOCK OPTIONS вы запросили,чтобы форма высветила
           больше строк,чем их буферировано.
 Действие: Увеличть количество буферизованных строк и/или
           уменьшить число высвечиваемых строк.
EIAD-49 : Invalid field name (Ошибка в имени поля)F
 Причина : Вы указали недопустимое имя поля.Допустимое имя поля должно удов-
           летворять правилам наименования объектов БД ORACLE.
 Действие: Указать правильное имя поля и повторить операцию.
EIAD-50 : Field with this name already exists for the current block (Поле с
           таким именем уже существует в текущем блоке )F
 Причина : Вы пытаетесь определить поле с именем,которое
           уже используется в текущем блоке.
 Действие: Удостоверьтесь,что вы не вводите заново поле,которое уже было
           введено.Если это так,присвойте полю другое имя или переименуйте
           то поле,из-за которого возникла данная ошибка.
EIAD-51 : This column does not exist in the specified table (Такого столбца
           в указанной таблице не существует)F
 Причина : Вы обращаетесь к столбцу таблицы,которого не существует.Это чаще
           всего означает,что вы даете неуправляющему полю имя,которое не
           соответствует имени столбца в таблице,связанной с текущим блоком.
 Действие: Ввести имя столбца в таблице или сделать это поле управляющим.
EIAD-52 : Datatype for this field does not match the column in the database
           table (Тип данных для этого поля не соответствует столбцу в
           таблице БД)F
 Причина : Вы определяете тип данных для поля,который не совместим с типом
           данных соответствующего столбца соответствующей таблицы.
 Действие: Проверить тип данных столбца в таблице и определить совместимый с
           ним тип данных для поля.
EIAD-53 : Control block does not correspond to a table in the database
           (Управляющий блок не соответствует таблице БД)F
 Причина : Вы выбираете опцию для управляющего блока,которая имеет значение
           только для неуправляющих блоков.
 Действие: Действий не требуется.Вы не можете определить такую опцию для
           данного блока до тех пор,пока не сделаете его неуправляющим.
EIAD-54 : Primery key field must be in the database table
           (Первичный ключ поля м.б. в таблице БД)F
Причина: Вы выбираете атрибут "Primery Key" для поля,не выбирая атрибута БД.
 Действие: Отменить несовместимость,исключая "Primаry key" или выбирая
           "Database Field".
EIAD-55 : This option is allowed only for displayed fields
           (Эта опция допустима только для отображаемых полей)F
 Причина : Вы выбираете характеристику поля,которой требуется характеристика
           "Displayed",которая,однако,не выбрана.
 Действие: Отменить несовместимость,исключая эту характеристику или выбирая
           "Displayed".
EIAD-56 : This option is allowed only for enterable fields
           (Эта опция допустима только для вводимых полей)F
 Причина : Вы выбираете характеристику поля,которой требуется характеристика
           "Input аllowed",которая,однако,не выбрана.
 Действие: Отменить несовместимость исключая эту характеристику или выбирая
           "Input аllowed".
EIAD-57 : Field length cannot be less than display length
           (Длина поля не м.б. меньше ширины вывода)F
 Причина : В окне SPECIFY VALIDATION вы определили длину поля,которая меньше
           ширины вывода поля,определенной для экрана.
Действие: Определить значение длины поля,которое не больше,чем ширина вывода
           поля или уменьшить ширину вывода поля,используя функцию [Resize].
EIAD-58 : Query length cannot be less than display length
           (Длина запроса не м.б. меньше ширины вывода)F
 Причина : В окне SPECIFY VALIDATION вы определили длину запроса,которая ме-
           ньше ширины вывода запроса,определенной для экрана.
 Действие: Определить значение длины запроса,которое не больше,чем ширина
           вывода запроса или уменьшить ширину вывода запроса,используя
           функцию [Resize].
EIAD-60 : Field is part of primary key; default not applicable (Поле являе-
           тся частью первичного ключа; умолчание неприемлемо)F
 Причина : В окне SPECIFY VALIDATION вы ввели элемент "DEFAULT" для поля,
           которое является частью первичного ключа блока.
 Действие: Удалить элемент "DEFAULT" из окна.Этот элемент не имеет смысла
           для поля,которое является частью первичного ключа.
EIAD-61 : You cannot specify a low value that is greater than the high va-
           lue (Вы не можете определить нижнее значение,которое больше,чем
           верхнее)F
 Причина : В появляющемся окне SPECIFY VALIDATION вы задаете элемент "RANGE
           Low" со значением,которое больше,чем значение элемента "RANGE
           High".
 Действие: Изменить один или оба элемента так,чтобы значение "RANGE Low" не
           превышало значения "RANGE High".
EIAD-62 : Displayed field is not allowed on page 0 (Высвечи-
           ваемое поле недопустимо на нулевой странице)F
 Причина : Вы пытаетесь выбрать атрибут отображения для
           поля на нулевой странице.
 Действие: Действий не требуется.
EIAD-70 : There is no room on current page (На текущей странице нет места)F
Причина: Вы пытаетесь создать блок по умолчанию на уже заполненной странице.
 Действие: Создать блок по умолчанию на новой странице.
EIAD-72 : At least one column should be selected (Должен
           быть выбран по крайней мере один столбец )F
 Причина : Вы пытаетесь создать блок по умолчанию,не выбирая столбцов.
 Действие: Выберите хотя бы один столбец.
EIAD-73 : Cannot fit on current page (Не подходит для текущей страницы)F
 Причина : Вы пытаетесь создать мультиблок,используя опцию умолчания,но ко-
           личество строк,высвечиваемых по вашему запросу,больше максималь-
           ного числа строк,которое м.б. отображено на текущей странице.
 Действие: Уменьшить количество высвечиваемых строк до максимального числа,
           которое м.б. отображено (или меньше максимального).
EIAD-74 : At least one row should be displayed (Должна
           быть высвечена по крайней мере одна строка )F
 Причина : Вы пытаетесь создать блок по умолчанию без определения количества
           строк,которые должны высвечиваться.
 Действие: Ввести число строк,которые должны высвечиваться ( от 1 до макси-
           мального значения количества строк).
EIAD-75 : Trigger statement must be entered or deleted first (Оператор
           триггера м.б. сначала введен или удален)F
 Причина : Вы пытаетесь определить новый шаг триггера до
           того,как определили текущий шаг.
 Действие: Ввести оператор триггера для текущего шага или удалить его.
EIAD-76 : Trigger name is invalid (Ошибка в имени триггера)
 Причина : Вы определили недопустимое имя триггера.
 Действие: Указать правильное имя триггера и повторить операцию.
 EIAD-77 : Trigger with this name already exists (Триггер с
           таким именем уже существует)F
 Причина : Вы пытаетесь создать триггер с именем,которое
           уже используется на этом уровне.
 Действие: Выберите другое имя или переименуйте триггер,
           из-за которого возникла ошибка.
EIAD-78 : Trigger with this name does not exist (Триггера с
           таким именем не существует)F
 Причина : Вы пытаетесь обратиться к триггеру,которого на этом уровне не
           существует.
 Действие: Ввести имя существующего триггера.Вызовите окно LIST TRIGGERS,
           чтобы посмотреть имена сушествующих на этом уровне триггеров.

+                           EПРИЛОЖЕНИЕE EВF
                        EОкна для разработки ФормF
     Это приложение является общим справочным руководством описывающим окна
SQL*Forms,которые используются для разработки форм.
     Приложение содержит:
 * блок-схемы,которые показывают как ориентироваться в структуре окон.
 * поэлементное описание каждого окна.

                        EПутеводитель по окнамF

    ЙНННННННННННННН»         LOGIN [Accept]     ЙНННННННННННННН»
    є      Окно    є           і   ^            є      Окно    є
    є     DEFINE   є DEFINE    і   і  FILE      є     FILE     є
    є      FOR M   є<--------ї і   і Ъ--------Д>є              є
    ИННННННННННННННј         і v   і і          ИННННННННННННННј
                    [Accept] і           ЙНННННННННННННН»     SAVE,DISCARD,^
                             А---------->є       Окно   є     DROP,[Accept]і
                                [Accept] є     CHOOSE   є------------------Щ
    ЙНННННННННННННН»------Д>             є      FORM    є------------Дї
    є     Окно     є                     ИННННННННННННННј             і
    є    DEFINE    є         і             і  ^    ^                  v
    є   FORM       є<--------Щ             і  і    А---------- GENERATE
    ИННННННННННННННј    LIST               і  і
                        CREATE             і  і
                     или MODIFY            і  і
                                           і  і            ЙНННННННННННННН»
                                           і  і [Accept]   є    Окно      є
    ЙНННННННННННННН»                       і  і            є    LIST      є
    є   Окно       є                       і  і            є    TABLES    є
    є   LIST       є LIST                  і  і            ИННННННННННННННј
    є   BLOCKS     є<--------ї             і  і         [Accept]і  ^
    ИННННННННННННННј         і             v  і                 v  іTABLES
         і[Accept]     ЙНННННННННННННН»  DEFAULT           ЙНННННННННННННН»
         А------------>є     Окно     є------Д >           є     Окно     є
                       є    CHOOSE    є                    є    DEFAULT   є
         Ъ------------>є     BLOCK    є            <------Дє     BLOCK    є
         і  [Accept]   ИННННННННННННННј            [Accept]ИННННННННННННННј
    ЙНННННННННННННН»         і  і  ^                              і ^
    є      Окно    є<--------Щ  і  і                      COLUMNS v і[Accept]
    є     LIST     є   FIELDS   і  і                    ЙНННННННННННННН»
    є     FIELDS   є            і  і                    є     Окно     є
    ИННННННННННННННј            і  і                    є    SELECT    є
                        CREATE  і  і                    є    COLUMNS   є
                     или MODIFY і  і                    ИННННННННННННННј
                                і  і [Accept]
                                v  і
         ЙННННННННННННННННННННННННННННННННННННННННН»
         є        ЭКРАННЫЙ ПОСТРОИТЕЛЬ ФОРМ        є
         ИНННННННННННННННННННННННННННННННННННННННННј
     [Select Block]і ^          [Create Field] і  ^
        +[Define]  v і[Accept]   или [Select]+ v  і[Accept]
       ЙНННННННННННННН»         [Define] ЙНННННННННННННН»
       є     Окно     є                  є      Окно    є
       є    DEFINE    є                  є     DEFINE   є
       є    BLOCK     є                  є     FIELD    є
       ИННННННННННННННј                  ИННННННННННННННј
            Рис.В-1

         ЙННННННННННННННННННННННННННННННННННННННННН»
         є        ЭКРАННЫЙ ПОСТРОИТЕЛЬ ФОРМ        є
         ИНННННННННННННННННННННННННННННННННННННННННј
          [Select Block] і    ^
             +[Define]   і    і [Accept]
                         v    і
    ЙНННННННННННННН»    TRIGGER  ЙНННННННННННННН»  TABLES  ЙНННННННННННННН»
    є     Окно     є     <------Дє      Окно    є------Д>  є     Окно     є
    є    CHOOSE    є             є     DEFINE   є          є     LIST     є
    є    TRIGGER   є------Д>     є     BLOCK    є  <------Дє    TABLES    є
    ИННННННННННННННј    [Accept] ИННННННННННННННј          ИННННННННННННННј
                          і ^          і ^
                 ORDERING і і          і і
                          і і  OPTIONS і і
                          і і [Accept] і і
                          v і          v і [Accept]
         ЙНННННННННННННННН »   ЙННННННННННННННННН»
         є       Окно      є   є       Окно      є
         є SPECIFY DEFAULT є   є SPECIFY BLOCK   є
         є     ORDERING    є   є     OPTIONS     є
         ИНННННННННННННННННј   ИНННННННННННННННННј
        Рис.В-2 Окна,используемые для определения блока.

         ЙННННННННННННННННННННННННННННННННННННННННН»
         є        ЭКРАННЫЙ ПОСТРОИТЕЛЬ ФОРМ        є
         ИНННННННННННННННННННННННННННННННННННННННННј
          [Create Field] і    ^
           или [Select]+ і    і [Accept]
           [Define]      і    і
                         v    і
    ЙНННННННННННННН»    TRIGGER ЙНННННННННННННН» COLUMNS ЙНННННННННННННН»
    є       Окно   є    <------Дє      Окно    є------Д> є     Окно     є
    є     CHOOSE   є            є    DEFINE    є         є     LIST     є
    є     TRIGGER  є------Д>    є     FIELD    є <------Дє    COLUMNS   є
    ИННННННННННННННј   [Accept] ИННННННННННННННј         ИННННННННННННННј
                      і ^              ^ і [Accept]
            ATTRIBUTESі і              і і VALIDATION
                      і і      [Accept]і і
                      і і      [Accept]і і
                      v і              і і
         ЙНННННННННННННННННН»  ЙНННННННННННННННННН»
         є        Окно      є  є       Окно       є
         єSPECIFY ATTRIBUTESє  єSPECIFY VALIDATIONє
         ИННННННННННННННННННј  ИННННННННННННННННННј
        Рис.В-3 Окна,используемые для определения поля.

      ЙНННННННННННННН»  ЙНННННННННННННН»  ЙНННННННННННННН»
      є      Окно    є  є     Окно     є  є     Окно     є
      є DEFINE FIELD є  є DEFINE BLOCK є  є DEFINE FORM  є
      ИННННННННННННННј  ИННННННННННННННј  ИННННННННННННННј
         ^    і TRIGGER    іTRIGGER ^    TRIGGER і    ^
         А----Е------------Е--------Е------------Е----Щ
              А----------Д>Е<------ДЕ------------Щ
                           v        і [Accept]
      ЙНННННННННННННН»   KEYSЙНННННННННННННН»     ЙНННННННННННННН»
      є     Окно     є  <----є     Окно     є<----є     Окно     є
      є     LIST     є       є    CHOOSE    єTYPESє     LIST     є
      є     KEYS     є---->  є    TRIGGER   є---->є     TYPES    є
      ИННННННННННННННј       ИННННННННННННННј     ИННННННННННННННј
                    [Accept]   і ^ і  ^ і ^
                    Ъ----------Щ і і  і і А----------ї
                    і Ъ----------Щ і  і А----------ї і
                    і і     CREATE і  і            і і
                    і і или MODIFY і  і            і і
               LIST v і  [Accept]  v  і  [Accept]  v і[Accept]
      ЙНННННННННННННН»  ЙНННННННННННННН»  ЙНННННННННННННН»
      є      Окно    є  є      Окно    є  є      Окно    є
      є LIST TRIGGER є  є TRIGGER STEP є  єDEFINE TRIGGERє
      ИННННННННННННННј  ИННННННННННННННј  ИННННННННННННННј
                         і ^        і ^
              ATTRIBUTES і і[Accept]і і
                         v і        і і
                        ЙНННННННННННННН»   CREATE
                        є     Окно     є
                        є TRIGGER STEP є
                        є  ATTRIBUTES  є
                        ИННННННННННННННј
       Рис.В-4 Окна,используемые для определения триггера.

                    EThe Choose Block WindowF
                      E(Окно выбора блока)F
EНазначениеF          Выбирать блок для создания,изменения,исправления,или
                        удаления.
EКогда высвечиваетсяF При выборе CREATE или MODIFY в окне СHOOSE FORM.
EСмотри такжеF        Главу 6.
EОбласти ввода         Name (имя)F Имя блока для создания или модификации.

                   EPage Number (номер страницы)F
     Номер страницы,выводимой на дисплей.
EДействия     CREATE (создать)F Создает новый блок пользователя с указан-
               ными именем и номером страницы и запускает экранный построи-
               тель,где вы можете проектировать блок.
EMODIFY (модифицировать)F Высвечивает указанные блок и N страницы и запус-
                            кает экранный построитель,где вы можете модифи-
                            цировать блок.
EDROP (удалить)F Удаляет указанный блок из формы (но не текст с ним связан-
                   ный).
ELIST (список)F Высвечивает окно LIST BLOCKS,откуда вы можете выбрать лю-
                  бой существующий блок для текущей формы.
EFIELDS (поля)F Высвечивает окно LIST FIELDS,которое показывает поля,уже
                  имеющиеся в блоке.
EDEFAULT (неявно,по умолчанию)F Высвечивает окно DEFAULT BLOCK,в котором
                                  вы можете создавать блок по умолчанию.
EPREVIOUS/NEXT (предыдущий/последующий)F Высвечивает имя предыдущего или
                 последующего блока в области ввода ENameF
EКлавиши  [Accept] (подтвердить)F Сохранить изменения и вернуться в окно
                                      CHOOSE FORM.
         E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вер-
                                             нуться в окно CHOOSE FORM.
         E[Select] (выбрать)F Выбрать действие,указанное курсором.

                         EThe Choose Form WindowF
                          E(Окно выбора формы)F
EНазначениеF      Выбирать форму для работы.
EКогда высвечиваетсяF При запуске SQL*Forms.
EСмотри такжеF     Главу 2.
EОбласти ввода    Name (имя)F Имя формы с которой вы хотите работать.
EДействия       CREATE (создать)F Создает новую форму с указанным именем и
                                    высвечивает окно CHOOSE BLOCK.
EMODIFY (модифицировать)F Выбирает (уже существующую) указанную форму и
                            высвечивает окно CHOOSE BLOCK,в котором вы може-
                            те выбрать блок для корректировки.
ELIST (список)F Высвечивает окно LIST FORMS,в котором вы можете выбрать
                  существующую форму для работы с ней.
ERUN (выполнить)F Выполняет указанную форму.
EDEFINE (определить)F Высвечивает окно DEFINE FORM,в котором вы можете из-
                        менить имя или заголовок указанной формы и определи-
                        ть для нее триггеры уровня формы.
ELOAD (загрузить)F Загружает форму из файла .INP (созданную другими или
                     иначе установленными версиями SQL*Forms.)
EFILE (файл)F Высвечивает окно FILE,где вы можете сохранять,удалять,переи-
                меновывать указанную форму или аннулировать изменения.
EGENERATE (генерировать)F Генерирует исполняемые (.INP и .FRM) файлы для
                            указанной формы,под именем,которое вы вводите в
                            появляющееся окно (нажмите [Accept],когда закон-
                            чите).
EКлавиши [Accept] (подтвердить)F Для выхода из SQL*Forms (c предупреждени-
                   ем о каких - либо несохраненных  изменениях [Exit/Cancel]).
        E[Select (выбрать)]F Выбрать действие,указанное курсором.

                   EThe Choose Trigger WindowF
                     E(Окно выбора триггера)F
EНазначениеF     Выбирать триггер для создания или модификации.
EКогда высвечиваетсяF При выборе TRIGGER в оконах DEFINE FIELD,DEFINE
                        BLOCK,или DEFINE FORM.
EСмотри такжеF     Главу 8.
EОбласти ввода    Name (имя)F Тип или имя триггера для создания или корре-
                   ктировки.
EДействия     CREATE (создать)F Создает новый триггер указанного типа и
               высвечивает окно TRIGGER STEP,где вы можете определить первый
               шаг.
EMODIFY (модифицировать)F Высвечивает первый шаг триггера,указанного в ок-
                            не TRIGGER STEP.
EDROP (удалить)F Удаляет указанный триггер из формы.
ELIST (список)F Высвечивает окно LIST TRIGGERS,в котором вы можете выбрать
                  существующий триггер.
EDEFINE (определить)F Высвечивает окно DEFINE TRIGGER,где вы можете изме-
                        нить имя или описание,появляющееся в меню указанного
                        триггера.
EKEYS (ключи)F Высвечивает окно LIST KEYS,которое показывает все имеющиеся
                 в распоряжении ключевые триггеры.
ETYPES (типы)F Высвечивает окно LIST TYPES,которое показывает все наличные,
                 не ключевые триггеры.
EPREVIOUS/NEXT (предыдущий/последующий)F Высвечивает имя предыдущего или
                последующего триггера в области ввода ENAMEF.
EКлавиши [Accept] (подтвердить)F Сохранить изменения и вернуться в окна
                DEFINE FIELD,DEFINE BLOCK или DEFINE FORM.
E[Exit/Cancel] (выйти /отменить)F Отменить изменения и вернуться в окна
                DEFINE FIELD,DEFINE BLOCK или DEFINE FORM.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                        EThe Comments WindowF
                        E(Окно комментариев)F
EНазначениеF    Вводить описательную или иную информацию о форме,блоке,по-
                  ле,триггере или шаге триггера.
EКогда высвечиваетсяF При выборе COMMENT в оконах DEFINE FORM,DEFINE
                        BLOCK,DEFINE FIELD,DEFINE TRIGGER,или TRIGGER STEP.
EСмотри такжеFEОбласти ввода  Comment area(unlabelled) (область коммента-
                  риев (без заголовка)) Текст комментария,который вы желаете
                  записать.
EДействия BACRWARD/FORWARD (вперед/назад)F "Прокручивает" окно комментария
                  вверх и вниз,сохраняя первую/последнюю строку для связки.
EDELETE (удалить)F Удаляет текст всего комментария.
EКлавиши  [Accept] (подтвердить)F Сохранить сделанные изменения и вернуть-
                   ся в окно,из которого вызвано окно COMMENTS.
E[Exit/Cancel] (выйти /отменить)F Отменить все изменения и вернуться в ок-
                   но,из которого вызвано окно COMMENTS.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                       EThe Default Block WindowF
                      E(Окно блока по умолчанию)F
EНазначение F     Определять схему расположения полей блока по умолчанию.
EКогда высвечиваетсяF При выборе DEFAULT  в окне CHOOSE BLOCK.
EСмотри такжеF     Главу 6.
EОбласти ввода    Table Name (имя таблицы)F Имя базовой таблицы или экран-
                  ной формы (view) для данного блока.
ERows Displayed (высвечиваемые строки)FЧисло строк для показа одновременно.
EBase Line (базовая строка)F Номер строки на экране,с которой будет начи-
                  наться блок.
EДействия       COLUMNS (столбцы)F Высвечивает окно SELECT COLUMNS,в кото-
                 ром вы можете выбрать столбцы для блока (если не требуется
                 выбирать все сразу).
ETABLES (таблицы)F Высвечивает окно LIST TABLES,в котором вы можете выбра-
                 ть базовую таблицу для блока.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                окно CHOOSE FORM.
E[Exit/Cancel] (выйти /отменить)F Отменить изменения и вернуться в окно
                CHOOSE FORM.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                       EThe Define Block WindowF
                       E(Окно определения блока)F
EНазначение     F Определять  характеристики  текущего блока.
EКогда высвечиваетсяF При нажатии [Select Block],а затем
                   [Define] в экранном построителе.
EСмотри такжеF     Главу 6.
EОбласти ввода    Seq # (порядковый номер)F Последовательность перемещения
                   курсора к данному блоку.
EName (имя)F Имя блока.
EDescription (описание)F Описание,которое будет появляться в меню блока.
ETable Name (имя таблицы)F Имя базовой таблицы или экранной формы для дан-
                   ного блока.Для определения управляющего блока оставьте
                   это имя пустым.
EДействия       TRIGGER (триггер)F Высвечивает окно СНООSE TRIGGER,в кото-
                 ром вы можете определить триггеры уровня блока.
EORDERING (порядок запроса)F Высвечивает окно SPECIFY DEFAULT ORDERING,в
                 котором вы можете определить,каким образом запросы будут
                 выбирать записи в блок.
EOPTIONS (опции)F Высвечивает окно SPECIFY BLOCK OPTIONS,в котором вы мо-
                 жете контролировать,каким образом записи выводятся и утвер-
                 ждаются.
ETABLES (таблицы)F Высвечивает окно LIST TABLES,в котором вы можете выбра-
                 ть базовую таблицу для блока.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                 экранный построитель.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                экранный построитель.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                     EThe Define Field WindowF
                     E(Окно определения поля)F
EНазначениеF      Определять характеристики поля.
EКогда высвечиваетсяF При помещении курсора в нужное поле в экранном пост-
                        роителе и нажатии [Select],a затем [Define].
EСмотри также  F   Главу 7.
EОбласти ввода Seq # (порядковый номер)F Последовательность,в которой кур-
                      сор перемещается к данному полю.
EName (имя)F Для полей БД (с атрибутом "Database"),имя соответствующего
                      столбца в базовой таблице.Для других полей,любое допу-
                      стимое имя,по которому вы можете отовсюду ссылаться
                      на это поле.
EСписок   Data Type (тип данных)F Выберите один из типов данных на экране,
                     чтобы определить какие символы разрешены в поле и как
                     они отображаются.Для детального обьяснения смотри "SQL*
                     Forms.Типы данных" в главе 7.
EДействия  TRIGGER (триггер)F Высвечивает окно CHOOSE TRIGGER,в котором вы
                     можете определить триггеры уровня поля.
EATTRIBUTES (атрибуты)F Высвечивает окно SPECIFY ATTRIBUTES,в котором вы
                     можете выбрать характеристики для данного поля.
EVALIDATIONF (проверять) Высвечивает окно,в котором вы можете определить
                     способы проверки значений в поле.
ECOLUMNS (столбцы)F Высвечивает окно LIST COLUMNS,в котором вы можете выб-
                     рать базовый столбец для поля.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                     экранный построитель.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                     экранный построитель
E[Select] (выбрать)F Выбрать действие или элемент списка,указанный курсо-
                     ром.

                      EThe Define Form WindowF
                     E(Окно определения формы)F
EНазначение F     Определять триггеры уровня формы и другие характеристики
                    формы.
EКогда высвечиваетсяF При выборе DEFINE в окне CHOOSE FORM.
EОбласти ввода    Name (имя)F Имя формы.
ETitle (заголовок)F Заголовок,несущий информацию о форме.
EДействия       TRIGGER (триггер)F Высвечивает окно CHOOSE TRIGGER,в кото-
                    ром вы можете определить триггеры уровня формы.
EКлавиши       [Accept] (подтвердить)F Coхранить изменения и вернуться в
                    окно CHOOSE FORM.
E[Exit/Cancel] (выйти /отменить)F Oтказаться от изменений и вернуться в
                    окно CHOOSE FORM.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                   EThe Define Trigger WindowF
                  E(Окно определения триггера)F
EНазначение F     Изменять имя триггера или название которым он представ-
                   лен в меню.
EКогда высвечиваетсяF При выборе DEFINE в окне CHOOSE TRIGGER.
EСмотри такжеF     Главу 6.
EОбласти ввода    Name (имя)F Тип или имя триггера.
EDescription (описание)F Для ключевых триггеров,описание,которое должно
                    появляться в меню,вызываемом по E[Show Function Keys]F.
EКлючи        Display in menus (высветить в меню)F Для ключевых триггеров
                    определяет,будет ли появляться клавиши в меню,вызываемом
                    по E[Show Function Keys]F.
EКлавиши       [Accept] (подтвердить)F Cохранить изменения и вернуться в
                    окно CHOOSE TRIGGER.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                    окно CHOOSE TRIGGER.
E[Select] (выбрать)F Выбрать или исключить ключ,указанный курсором.

                         EThe File WindowF
                           E(Окно файла)F
EНазначение F     Сохранять,копировать,переименовывать,удалять форму или
                    аннулировать изменения в форме,которая находится в рабо-
                    чей области.
EКогда высвечиваетсяF При выборе FILE в окне CHOOSE FORM,либо при выборе
                    другого действия,приводящего к очистке рабочей области.
EСмотри такжеF     Главу 4.
EДействия       SAVE (сохранить)F Заносит текущую форму в БД и возвращает
                    в окно CHOOSE FORM
EDISCARD (отказаться)F Прекращает работу с текущей формой без сохранения
                     изменений и возвращает в окно CHOOSE FORM.
ESAVE AS (сoхранить как)F Сохраняет текущую форму под новым именем,которое
                     вы вводите в появляющееся окно (после ввода нажмите
                     [Accept]).Оставляет оригинал нетронутым и возвращает в
                     окно CHOOSE FORM.
ERENAME (переименовать)F Сохраняет текущую форму под новым именем,которое
                     вы вводите в появляющееся окно (после ввода нажмите
                     [Accept]).Удаляет оригинал и возвращает в окно CHOOSE
                     FORM.
EDROP (удалить)F Совсем удаляет текущую форму из БД,удаляет ее из рабочей
                     области и возвращает в окно CHOOSE FORM.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                     окно CHOOSE FORM.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                     окно CHOOSE FORM.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                      EThe List Blocks WindowF
                       E(Окно списка блоков)F
EНазначениеF      Просматривать и выбирать блок в текущей форме.
EКогда высвечиваетсяF При выборе LIST в окне CHOOSE BLOCK.
EСписок        Block Names (имя блока)F Выводит на экран все блоки текущей
                    формы.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                    окне вперед или назад список имен блоков.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно CHOOSE BLOCK и
                    скопировать имя выбранного блока в область ввода ENameF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно CHOOSE BLOCK без копи-
                    рования имени выбранного блока.
E[Select] (выбрать)F Выбрать или исключить блок,указанный курсором.

                      EThe List Columns WindowF
                      E(Окно списка столбцов)F
EНазначение F     Просматривать и выбирать столбец таблицы для текущего
                    поля.
EКогда высвечиваетсяF При выборе COLUMNS в окне DEFINE FIELD.
EСписок        Columns Names (имена столбцов)F Выводит на экран все столб-
                    цы таблицы,связанной с текущим блоком.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                    окне вперед или назад список имен столбцов.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно DEFINE FIELD и
                   скопировать имя выбранного столбца в область ввода ENameF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно DEFINE FIELD,без копи-
                    рования имени выбранного столбца.
E[Select] (выбрать)F Выбрать или исключить столбец,указанный курсором.

                       EThe List Fields WindowF
                        E(Окно списка полей)F
EНазначение  F    Просматривать поля и их расположение в текущем блоке.
EКогда высвечиваетсяF При выборе FIELDS в окне CHOOSE BLOCK.
EСписок        Field Names (имена полей)F Выводит все поля в текущем бло-
                   ке,их порядковый N и N страницы,на которой они располо-
                   жены.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                   окне вперед или назад список имен полей.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно CHOOSE BLOCK.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно CHOOSE BLOCK.

                        EThe List Forms WindowF
                         E(Окно списка форм)F
EНазначениеF      Просматривать и выбирать формы для последующей работы.
EКогда высвечиваетсяF При выборе LIST в окне CHOOSE FORM.
EСписок        Form Names (имена форм)F Выводит все формы БД с текущим
                   именем пользователя.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                   окне вперед или назад список имен форм.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно CHOOSE BLOCK и
                   скопировать имя выбранной формы в область ввода ENameF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно CHOOSE BLOCK без копи-
                   рования имени выбранной формы.
E[Select] (выбрать)F Выбрать или исключить форму,указанную курсором.

                         EThe List Keys WindowF
                         E(Окно списка ключей)F
EНазначениеF      Просматривать и выбирать типы ключевого триггера.
EКогда высвечиваетсяF При выборе KEYS в окне CHOOSE TRIGGER.
EСписок        Key Names (имена ключей)F Выводит все имеющиеся типы ключе-
                   вых триггеров.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                   окне вперед или назад список имен ключевых триггеров.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно CHOOSE TRIGGER и
                   скопировать выбранный тип триггера в область ввода ENAMEF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно CHOOSE TRIGGEER без
                   копирования выбранного типа триггера.
E[Select] (выбрать)F Выбрать или исключить тип триггера,указанный курсором.

                        EThe List Tables WindowF
                         E(Окно списка таблиц)F
EНазначение  F    Просматривать и выбирать таблицы,связанные с текущим
                   блоком.
EКогда высвечиваетсяF При выборе TABLES в окне DEFINE BLOCK или DEFAULT
                   BLOCK.
EСписок        Table Names (имена таблиц)F Выводит все таблицы БД,принад-
                   лежащие текущему пользователю.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                   окне вперед или назад список имен таблиц.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно DEFINE BLOCK или
                   DEFAULT BLOCK и скопировать выбранный тип таблицы в
                   область ввода ETABLE NAMEF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно DEFINE BLOCK или
                   DEFAULT BLOCK без копирования имени выбранной таблицы.
E[Select] (выбрать)F Выбрать или исключить таблицу,указанную курсором.

                       EThe List Triggers WindowF
                        E(Окно списка триггеров)F
EНазначениеF      Просматривать и выбирать существующие триггеры для пос-
                   ледующей работы с ними.
EКогда высвечиваютсяF При выборе TRIGGERS в окне CHOOSE TRIGGER.
EСписок        Trigger Names (имена триггеров)F Выводит все триггеры,опре-
                   деленные на текущем уровне.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                   окне вперед или назад список имен триггеров.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно CHOOSE TRIGGER и
                   скопировать выбранное имя триггера в область ввода ENAMEF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно CHOOSE TRIGGEER без ко-
                   пирования выбранного имени триггера.
E[Select] (выбрать)F Выбрать или исключить тип триггера,указанный курсором.

                        EThe List Types WindowF
                        E(Окно списка типов)F
EНазначение F     Просматривать и выбирать тип триггера.
EКогда высвечиваетсяF При выборе TYPES в окне CHOOSE TRIGGER.
EСписок        Trigger Types (типы триггеров)F Выводит все имеющиеся типы
                   неключевых триггеров текущего уровня.
EДействия       PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в
                   окне вперед или назад список типов триггеров.
EКлавиши       [Accept] (подтвердить)F Вернуться в окно CHOOSE TRIGGER и
                   скопировать выбранный тип триггера в область вводаENAMEF.
E[Exit/Cancel] (выйти /отменить)F  Вернуться в окно CHOOSE TRIGGEER без ко-
                   пирования выбранного типа триггера.
E[Select] (выбрать)F Выбрать или исключить тип триггера,указанный курсором.

                       EThe Select Columns WindowF
                         E(Окно выбора столбцов)F
EНазначениеF      Выбирать столбцы в таблице для блока по умолчанию.
EКогда высвечиваетсяF При выборе COLUMNS в окне DEFAULT BLOCK.
EСмотри такжеF     Главу 6.
EСписок        Column names (имена столбцов)F Выводит все столбцы в табли-
                   це,выбранной для блока по умолчанию.
EДействия       ALL (все)F Выбирает все  столбцы из списка.
ENONE (ни одного)F Исключает все столбцы из списка.
PREVIOUS/NEXT (предыдущий/последующий)F "Пролистывает" в окне вперед или
                   назад список имен столбцов.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                   окно DEFAULT WINDOW.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно DEFAULT BLOCK.
E[Select] (выбрать)F Выбрать или исключить столбец,указанный курсором.

                      EThe Specify Attributes WindowF
                      E(Окно определения атрибутов)F
EНазначение F     Определять параметры текущего поля.
EКогда высвечиваетсяF При выборе ATTRIBUTES в окне DEFINE FIELDS.
EСмотри такжеF     Главу 7,для подробного описания каждого атрибута.
EКлючи        Database Field (поле БД)F Поле,соответствующее столбцу базо-
                   вой таблицы для данного блока.
EPrimary Key (первичный ключ)F  Поле,являющиеся частью уникального иденти-
                   фикатора записей.
EDisplayed (высветить)F Поле,высвечиваемое во время выполнения формы.
EInput allowed (ввод разрешен)F  Оператор может вводить или изменять значе-
                   ния в поле.
EQuery allowed (запрос разрешен)F  Оператор может ввести в поле условие
                   запроса.
EUpdate allowed (корректировка разрешена)F Оператор может изменить значе-
                   ние поля в любой записи,возвращенной запросом.
EUpdate if NULL (корректировка если пусто)F Оператор может изменить только
                   пустые значения в записях,возвращенных запросом.
EFixed Length (фиксированная длина)F Длина значения,введенного в поле,д.б.
                   равна длине поля.
EMandatory (ввод обязателен)F Поле должно содержать только не нулевые
                   значения.
EUppercase (прописные буквы)F   Буквы,вводимые в это поле в нижнем регис-
                   тре (строчные),преобразуются в буквы на верхнем регистре
                   (прописные).
EAutoskip (автоматическое перемещение)F Как только оператор введет послед-
                   ний символ в поле,курсор автоматически перемещается на
                   следующее поле.
EAutomatic help (автоматическая помошь)F При перемещении курсора в поле
                   автоматически появляется текст подсказки.
ENO echo (без эха)F Значение поля всегда высвечивается как пробелы,даже
                   если само поле видимо.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                   окно DEFINE FIELD.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно DEFINE FIELD.
E[Select] (выбрать)F Выбрать или исключить атрибут,указанный курсором.

                    EThe Specify Block Options WindowF
                     E(Окно определения опций блока)F
EНазначение F     Управлять способом отображения и проверки данных записей
                   в текущем блоке.
EКогда высвечиваетсяF При выборе OPTIONS в окне BLOCK WINDOW.
EСмотри также F    Главу 6.
EКлючи        Check for unique Key (проверка на уникальный ключ)F Проверя-
                   ет,действительно ли запись,введенная или обновленная в
                   блоке,имеет уникальный набор значений в полях первичного
                   ключа.
EDisplay in block menu (Отображение в меню блоков)F Выводит описание блока
                   в меню блоков.
EОбласти ввода    Number of Rows displayed (число высвечиваемых строк)F
                   Количество записей,одновременно выводимых в блоке.
ENumber of Rows buffered (число буферизованных строк)F Количество записей,
                   одновременно сохраняемых в основной памяти.
ENumber of Lines per Row (число строк экрана на одну запись)F  Количество
                   строк экрана,выделяемых для каждой записи в блоке.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                   окно DEFINE BLOCK.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно DEFINE BLOCK.
E[Select] (выбрать)F Выбрать или исключить ключ,указанный курсором.

                     EThe Specify Default OrderingF
          EWindow(Окно определения порядка выборки по умолчанию)F
EНазначение F     Управлять способом выборки записей в текущий блок.
EКогда высвечиваетсяF При выборе ORDERING в окне DEFINE BLOCK.
EСмотри такжеF     Главу 6.
EОбласти ввода    WHERE/ORDER BY clause for QUERY (фраза WHERE/ORDER BY для
                   запроса)F Определяет фразы SQL WHERE и / или ORDER BY,
                   включаемые в каждый запрос для блока.Фраза WHERE устанав-
                   ливает условия,которым должны удовлетворять строки,а фра-
                   за ORDER BY описывает порядок их вывода.Если включаются
                   обе фразы,фраза WHERE д.б. первой.
EДействия       FORWARD/BACKWARD (вперед /назад)F Пролистывает оператор
                   WHERE/ORDER BY вверх или вниз в окне.
EDELETE (удалить)F Удаляет оператор WHERE/ORDER BY для блока.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться в
                   окно DEFINE BLOCK.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно DEFINE BLOCK.
E[Select] (выбрать)F Выбрать действие,указанное курсором.

                      EThe Specify Run Options WindowF
                    E(Окно определения опций выполнения)F
EНазначение F     Дает возможность управлять памятью,удовлетворять требо-
                   вания оператора и отлаживать текущую форму.
EКогда высвечиваетсяF При нажати [Run-Options Window] при создании формы.
EСмотри также F      Главу 4.
EКлючи        Buffer records with file (буферизация записей в файле)F Эко-
                   номит память(но замедляет обработку).С помощью буфериро-
                   вания выбираемых при запросе записей в файле,а не в памя-
                   ти.
EDisplay menu (вывод меню)F При выполнениии формы выводит меню блоков,вме-
                   сто того,чтобы переходить непосредственно к первому блоку.
EOptimize SQL processing (оптимизация функционирования SQL)F Если  ключ не
                   выбран,экономит память (но замедляет обработку),назначая
                   отдельный курсор (область памяти) только тем шагам триг-
                   гера,которые вы обозначаете специально ( а не всем шагам).
EQuiet mode (режим тишины)F  Отменяет звуковой сигнал при автоматическом
                   переходе курсора,при выводе вспомогательной информации
                   или некоторых сообщений.
EStatistics (статистика)F  Высвечивает количество курсоров (областей памя-
                   ти),установленных на конец сеанса Run (выполнения).
EOptimize transaction processing (оптимизация процесса транзакции)F   Если
                   ключ не выбран,экономит память (но замедляет обработку),
                   назначая отдельный курсор (область памяти) только опера-
                   торам запроса SELECT.
EDebug mode (режим отладки) F  Выводит сопутствующие сообщения о работе
                   триггера и других состояниях формы во время ее выполнения.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения и вернуться к
                   тому,что вы делали.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться к
                   тому,что вы делали.
E[Select] (выбрать)F Выбрать или исключить действие,указанное курсором.

                    EThe Specify Validation WindowF
                  E(Окно определения проверки данных)F
EНазначение F     Проверять вводимые оператором значения в текущее поле,а
                   также содействовать этому вводу.
EКогда высвечиваетсяF При выборе VALIDATION в окне DEFINE FIELD.
EСмотри такжеF     Главу 7.
EОбласти ввода    Field Length (длина поля)F  Максимальное количество сим-
                   волов,которое можно ввести в поле.Если вводится количест-
                   во символов,превышающее длину поля,то оператор может вос-
                   пользоваться [Left] (или [Scroll Left] ) и [Right] (или
                   [Scroll Right]) для прокрутки значения в поле.
EQuery Length (длина запроса)F Максимальное количество символов,которое
                   м.б. введено в поле как условие запроса.
ECopy Field Value from (копировать значение поля из)F Блок и поле,откуда
                   д.б. скопирована величина в это поле.Вы можете использо-
                   вать эту область ввода для координации мультиблоков в фо-
                   рме.
EDefault (по умолчанию)F Значение,появляющееся по умолчанию в поле,для но-
                   вых записей.
ERange (интервал)F Минимальное и максимальное возможные значения для поля.
EList of Values (список значений)F Таблица и столбец,содержащие список воз-
                   можных значений для поля.Этот список используется не для
                   проверки,а для подсказки при нажатии оператором [List
                   Fields Values] (вместо этого вы можете использовать триг-
                   гер для проверки таблицы и столбца).
EHelp (помощь)F Когда оператор нажимает [Help] в текущем поле,появляется
                   сообщение с об`яснением.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения в окно DEFINE
                   FIELD.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно DEFINE FIELD.

                        EThe Trigger Step WindowF
                         E(Окно шагa триггера)F
EНазначение F     Задавать команду,которая должна выполняться в текущем
                   триггере.
EКогда высвечиваетсяF При выборе CREATE или MODIFY в окне CHOOSE TRIGGER.
EСмотри также F      Главы 8-9.
EОбласти ввода    Seq# (порядковый N)F  Последовательность,в которой этот
                   шаг будет обычно выполняться.(Для изменения порядка упра-
                   вления вы можете также воспользоваться метками шага).
ELabel (метка)F Имя,по которому вы можете перейти на этот шаг из любого
                   места в триггере.
ETrigger Area(unlabelled)   (область триггера)F Команда SQL или SQL*Forms
                   или подсоединяемая программа пользователя,которая д.б.
                   выполнена в этом месте в триггере.
EMessage if trigger step fails (сообщение если шаг триггера неудачен)F
                   Cooбщение,которое появится на экране,если шаг зaвершится
                   неудачно.
EДействия       Create (создать) F Очищает окно,чтобы вы могли создавать
                   новый шаг триггера.Шаг,который вы уже определили сохраня-
                   ется в памяти.
ECOPY (копировать)F Дублирует текущий шаг в качестве следующего шага в
                   триггере.Если вы желаете,то можете модифицировать или из-
                   менить порядковый N.
EDROP (удалить)F Удаляет текущий шаг из триггера.
EATTRIBUTES (атрибуты)F Высвечивает окно TRIGGER STEP ATTRIBUTES,в котором
                   вы можете управлять тем,что произойдет,когда шаг заверши-
                   тся успешно или неудачно.
EFORWARD/BACKWARD (вверх/вниз)F  " Пролистывает" текущий шаг триггера вве-
                   рх или вниз в окне.
EPREV STEP/NEXT STEP (предыдущий шаг/последующий шаг)F Высвечивает преды-
                   дущий или последующий,существующий шаг в окне.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения в окно CHOOSE
                   TRIGGER.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно CHOOSE TRIGGER.

                    EThe Trigger Step AttributesF
                 EWindow(Окно атрибутов шага триггера)F
EНазначение  F    Конкретно определять,что произойдет,если текущий шаг
                   триггера завершится успешно,либо неудачно и выделять па-
                   мять для этого шага.
EКогда высвечиваетсяF При выборе ATTRIBUTES в окне TRIGGER STEP.
EСмотри также F    Главу 8
EКлючи        Abort trigger when step fails  (Прервать триггер в случае не-
                   удачного завершения шага)F Останавливает выполнение три-
                   ггера,если шаг завершается неудачно.Отменяется меткой не-
                   удачного завершения,если таковая введена.
EReverse return code (Установить значение кода на противоположный)F Уста-
                   навливает значение критерия успешного и неудачного завер-
                   шения шага на противоположное.
EReturn success when aborting trigger (Возвратить код успешного завершения,
                   когда триггер аварийно прерывается)F Заставляет триггер
                   завершиться успешно,если он прервался из-за неудачного
                   завершения текущего шага.Игнорируется,если ключ Abort
                   trigger when step fails не выбран.
ESeparate cursor data area  (выделить область курсора для данных)F  Резе-
                   рвирует область памяти для этого шага триггера (и ускоря-
                   ет его обработку),даже если ключ Optimize SQL processing
                   в окне SPECIFY RUN WINDOW не был выбран.Действителен то-
                   лько для команд SQL.
EОбласти ввода    Success label/Failure label (метки успешного и неудачного
                   завершения)F  Определяет следующий шаг для выполнения,
                   если триггер завершится успешно или неудачно.
EКлавиши       [Accept] (подтвердить)F Сохранить изменения в окно TRIGGER
                   STEP.
E[Exit/Cancel] (выйти /отменить)F Отказаться от изменений и вернуться в
                   окно TRIGGER STEP.

+                            EПРИЛОЖЕНИЕF EСF
                 EПодсоединяемые Программы ПользователяF
     Подсоединяемые программы пользователя являются программами,написанными
на традиционном языке программированмя (например,Си),и вызываемыми из шага
триггера.Подсоединяемая программа может выводить сообщения и выполнять мно-
гие типы обработки данных (например,вычисления и просмотр таблиц),которые
находятся вне области деятельности команд SQL и SQL *Forms.Она может также
выполнять многие типы обработки данных быстрее,чем это делают команды SQL.
     Глава 9,"Синтаксис триггеров",знакомит с подсоединяемыми программами и
объясняет,как с помощью шага триггера вызывать эти программы и передавать к
ним значения параметров.Данное приложение является руководством по написанию
и применению подсоединяемых программ.Оно охватывает:
 * процесс написания подсоединяемых программ
 * замечания по написанию подсоединяемых программ
 * соглашения по передаче параметров и сообщениям об ошибках
 * чтение и запись значений формы
 * вставку и корректировку записей таблицы
 * обнаружение и обработку ошибок
 * применение подсодиняемых программ в форме

        EПроцесс написания подсоединяемых программ пользователяF
     Подсоединяемые программы м.б. написаны на каком-либо из языков высокого
уровня.В настоящее время поддерживаются языки Си,КОБОЛ,ФОРТРАН,ПЛ/1 и ПАСКА-
ЛЬ.Не всякая из существующих OC поддерживает все вышеперечисленные языки
программирования; для получения более подробной информации см."ORACLE.Уста-
новка и руководство по использованию " для вашей системы.
     На каком бы языке ни была написана подсоединяемая программа,она может
использовать возможности ORACLE с помощью включаемых в нее команд SQL.Язык,
используемый для написания подсоединяемых программ,часто называют главным
языком подсоединяемых программ,так как он является "хозяином" для команд SQL.
Вносимые в программу команды SQL имеют свой собственный синтаксис,отличный
от синтаксиса главного языка.Пример 1 показывает,каким образом в подсоединя-
емую программу,написанную на языке Си,м.б. включены команды SQL.
     Перед компиляцией подсоединяемая программа д.б. обработана посредством
РСС (аббревиатура для словосочетания Precompiler,Common),который транслирует
команды SQL в вызовы функций,изображаемые на главном языке.Далее для компи-
ляции выхода прекомпилятора используется стандартный компилятор главного
языка.При необходимости модификации программы сделайте изменения исходного
модуля и снова запустите РСС.
     Для каждого главного языка РСС вызывается с помощью соответствующего
параметра командной строки.Главные языки называются следующим образом: Pro*C
- при использования с языком программирования Си; Pro*COBOL - для КОБОЛа;
Pro*FORTRAN - для ФОРТРАНа; Pro*PL/1 - для ПЛ/1; и Pro*PASCAL - для ПАСКАЛя.
     Pro*C,Pro*COBOL,Pro*FORTRAN,Pro*PL/1 и Pro*PASCAL описываются соответс-
твенно в "Pro*C.Руководство пользователя","Pro*COBOL.Руководство пользовате-
ля","Pro*FORTRAN.Руководство пользователя","Pro*PL/1.Руководство пользовате-
ля","Pro*PASCAL.Руководство пользователя".Дополнительная информация о вклю-
чении команд SQL в программы на главном языке (в случае подсоединяемых прог-
рамм и в других случаях) м.б. найдена в документе "Pro*SQL.Руководство поль-
зователя".При дальнейшем описании предполагается,что вы хорошо знакомы с
этими документами.
     Ниже описывается алгоритм действий,которые вы должны выполнить,чтобы
включить подсоединяемую программу в форму:
 1.Использовать утиллиту GENXTB,чтобы добавить элемент,объявляющий новую по-
   дсоединяемую программу,к таблице программ IAPXTB модуля IAPXIT (компонент
   IAP).
 2.Написать подсоединяемую программу на выбранном главном языке.
 3.Запустить соответствующий прекомпилятор для исходного файла подсоединяе-
   мой программы.
 4.Для результата выполнения предыдущей операции запустить соответствующий
   компилятор.
 5.Создать новую версию IAP (компонент SQL*Forms,который запускает форму) с
   помощью компоновки совместно стандартных модулей IAP,модифицированного
   модуля IAPXTB и новых модулей подсоединяемой программы.
 6.В форме определить шаг триггера,"включающий" подсоединяемую программу.
 7.Если подсоединяемая программа содержит ошибки,найти их и сделать необхо-
   димые изменения в исходном файле.Вернуться к шагу 3.
 8.После завершения отладки подсоединяемой программы проинструктировать опе-
   ратора относительно использования новой версии IAP при выполнении формы.
   (Если новая версия IAP заменяет стандартную,это делать необязательно.)
   Все эти шаги подробнее описываются в дальнейшей части данного приложения.

             EЗамечания по написанию подсоединяемых программF
     Как показано в примерах ниже,для переноса на другую страницу и опреде-
ления границы фраз в командах SQL вы должны использовать соглашения по пере-
носу и ограничению,которые существуют в главном языке.

                                EВ Си:F
        EXEC IAF GET EMP.ENAME,EMP.EMPNO INTO :i1,:c1;

                              EВ КОБОЛе:F
        EXEC IAF GET EMP.ENAME,EMP.EMPNO
        INTO :I1,:C1
        END-EXEC.

                             EВ ФОРТРАНе:F
        EXEC IAF GET EMP.ENAME,EMP.EMPNO INTO :I1,:C1

                              EВ ПЛ/1:F
        EXEC IAF GET EMP.ENAME,EMP.EMPNO INTO :I1,:C1;

                             EВ ПАСКАЛе:F
        EXEC IAF GET EMP.ENAME,EMP.EMPNO INTO :i1,:c1;

     В операторах главного языка нижний и верхний регистры используются так-
же,как если бы они использовались в обычной программе главного языка.Больши-
нство частей команды SQL м.б. написано с использованием любой комбинации ве-
рхнего и нижнего регистров,но обычно она полностью записывается с использо-
ванием только верхнего регистра.В этом смысле ссылки к переменным подсоеди-
няемой программы (переменным пограмммы на главном языке) являются исключени-
ем; они м.б. написаны по правилам главного языка.
     Имя входной точки подсоединяемой программы становится именем самой под-
соединяемой программы.Имя м.б. допустимым именем файла,входная точка именуе-
тся в соотвествии с правилами вашей операционной системы и главного языка,а
также по правилам присвоения имен объекту БД ORACLE (например,имя не м.б.
резервированным словом ORACLE).Даже если главный язык и ОС допускают запись
имен функций прописными буквами,имя подсоединяемой программы должно полнос-
тью состоять из заглавных букв (верхний регистр),поскольку SQL*Forms перед
выполнением поиска подразумевает,что имя программы указано заглавными буква-
ми.
     Необходимо избегать присвоения имен,которые совпадают с именами команд
SQL*Forms и функциональными кодами (названиями функций); кроме того,необхо-
димо соблюдать осторожность для избежания конфликтов между именами подсоеди-
няемых программ и внешними именами,используемыми в самом SQL*Forms.Так как
SQL*Forms является большой,сложной программой,он имеет множество внешних
(предварительно заданных) имен,использования которых вы должны избегать.Если
вы беспокоитесь по поводу возможных конфликтных ситуаций,посмотрите карту
компоновки IAP (компонент SQL*Forms,выполняющий форму).
     Разнообразие сервисных услуг SQL*Forms позволяет использовать подсоеди-
няемые программы для таких целей,как,например,отображение информации на эк-
ране,считывание значений из полей и выполнение команд SQL.Эти услуги м.б.
использованы с помощью вызовов функций,написанных на главном языке или с по-
мощью включаемых в программу команд SQL,которые РСС может реализовать через
функциональные вызовы главного языка.

                    ECвязь с ORACLE необязательнаF
     Подсоединяемая программа не обязательно должна выполнять команду EXEC
SQL CONNECT,как это показано в примерах стандартных программ из руководств
по прекомпиляторам (см.выше).Эта функция выполняется самим SQL*Forms.

            EОграничения по вводу/выводу главного языкаF
     В зависимости от используемой вами OC и главного языка вы можете быть
не допущены к использованию из подсоединяемых программ вызовов I/O главного
языка.Это происходит потому,что поддерживающая система I/O главного языка
вступает в противоречие с программами,которые SQL*Forms использует для I/O.
Ограничения не относятся к подсоединяемым программам,написанным на языке Си.
Это происходит потому,что SQL*Forms сам написан на Си,таким образом снимая
данное противоречие.

                 EСоглашения по передаче параметровF
     Для осуществления интерфейса с SQL*Forms подсоединяемые программы поль-
зователя м.б. написаны с соблюдением соответствующих соглашений по приему и
передаче параметров.Следующие 2 раздела описывают виды соглашений,применяю-
щихся для каждого из главных языков.
     В последующих же разделах дается подробное описание соглашений,которые
применяются для каждого из поддерживаемых главных языков.

                        EПередача значенийF
     При вызове пользовательской подсоединяемой программы ей передается сим-
вольный строковый параметр,содержащий имя подсоединяемой программы и параме-
тры,указанные в шаге триггера,активизирующем эту программу.Начальный символ
"#" не передается.Например,если подсоединяемая программа VALIDATE "включает-
ся" с помощью шага триггера следующим образом:
        #VALIDATE 10 25 A         ,

то параметром, передаваемым к VALIDATE является "VALIDATE 10 25 A".
     SQL*Forms сжимает последовательности так называемых чистых символов
(пробелов,табуляций и т.д.) до одного пробела.Он (SQL*Forms) не переводит
буквы к какому-либо единому типу написания (верхний или нижний регистры).
     Если подсоединяемая программа вызывается из нескольких различных шагов
триггера,шаги могут передавать разные параметры для выполненя программой ра-
зличных действий.
     Подсоединяемой программе передаются также любые сообщения об ошибке,оп-
ределенные для шага триггера,активизирующего подсоединяемую программу,и
флаг,показывающий,является ли программа пользователя "включенной" в режиме
запроса.
     Параметры являются не только средством передачи информации к подсоеди-
няемой программе; можно также использовать значения переменных SQL*Forms в
подсоединяемой программе следующим образом:
 * Вы можете использовать указатели " [блок.]поле",глобальные переменные и
системные переменные не посредственно в операторах EXEC IAF GET и EXEC IAF
PUT.Например,фразы:
            EXEC IAF GET ORDERS.ORDEID INTO :val
            EXEC IAF GET GLOBAL.ID INTO :val
            EXEC IAF GET SYSTEM.CURRENT_FIELD INTO :val

назначают для val значение поля ORDERS.ORDERID,значение глобальной перемен-
ной GLOBAL.ID и имя текущего поля соответственно.
 * Хотя прекомпилятор не допускает присутствие амперсанда непосредственно в
   указателе переменной наподобие указателя "&[блок.]поле",вы можете исполь-
   зовать такой синтаксис переменных прекомпилятора в операторах EXEC IAF
   GET И EXEC IAF PUT.
          Например,если переменная прекомпилятора :name содержит значение
   &ONE.NAME,тогда оператор
            EXEC IAF GET :name INTO :val
   будет назначать для :val значение поля или глобальной переменной,чье имя
   содержится в поле  ONE.NAME .

                            EВозврат значенийF
     Когда подсоединяемая программа пользователя возвращает управление SQL*
Forms,она должна возвратить значение,идентифирующее успех,неудачу или фата-
льную ошибку.Эти 3 типа результата являются аналогами результатов,которые
может возвращать команда SQL и имеют то же самое значение для SQL*Forms (с
одним исключением,указанным ниже).Таким образом:
 * Успех означает,что подсоединяемая программа завершилась успешно.SQL*Forms
   будет выполнять переход на метку успешного завершения или к следующему
   шагу (если не выбран ключ "Reverse return code").
 * Неудача означает,что подсоединяемая программа обнаружила ошибку,такую,как
   например,недопустимое значение поля.SQL*Forms на это отреагирует точно
   также,как он реагирует на неудачу команды SQL.
 * Фатальная ошибка означает,что подсоединяемой программой обнаружено усло-
   вие,например,ошибка при выполнении команды SQL,по которому дальнейшее ра-
   звитие процесса становиться невозможным.Реакция SQL*Forms при этом будет
   аналогична реакции на фатальную ошибку в команде SQL.
Существует одно исключение из того правила,что SQL*Forms одинаково "отзывае-
тся" на код состояния,возвращенный подсоединяемой программой и тот же код
состояния,возвращенный командой SQL.С помощью вызова функции SQLIEM в подсо-
единяемой программе можно указать сообщение,которое будет отображено в стро-
ке сообщений в случае неудачи.Это сообщение будет выводится и посредством
функции [Display Error] после появления фатальной ошибки.SQL*Forms будет то-
гда высвечивать указанное сообщение взамен сообщения,определенного для шага.

                EСоглашения по передаче параметров в СиF
     Для подсоединяемых программ,написанных на языке Си,SQL*Forms поддержи-
вает 2 различных соглашения по передаче параметров.Этот раздел описывает
текущие соглашения,которые должны использоваться для всех вновь создаваемых
программ.Подсоединяемые программы пользователей,которые написаны с использо-
ванием старых соглашений,могут и в дальнейшем выполняться без изменений.
     Программа на Си из примера 1 иллюстрирует соглашения по передаче пара-
метров для пользовательских программ.Обратите внимание на следующие аспекты
этих соглашений:
 * Строки "cmd" и "msg" необязательно ограничиваются нулевым символом.Для
   задания длины "cmd" и "msg" можно использовать "cmdlen" и "msglen".
 * Параметры "cmdlen","msglen" и "query" не являются числовыми значениями,но
   являются укзателями (числа).Так,например,вы можете указать длину "cmd"
   как "*cmdlen".
                               EПример 1F
     #include   /* Традиционно; не обязательна для SQL*Forms */
/* Переменные подсоединяемой программы,указанные в командах EXEC SQL или
   EXEC IAF,м.б. объявлены в секции DECLARE .*/
     EXEC SQL BEGIN DECLARE SECTION;
      int i1;
      char c1 [64];
      float f1;
     EXEC SQL END DECLARE SECTION;
 /* Эта команда Pro*C определяет символы,ипользуемые для интерфейса с
    SQL*Forms.*/
     EXEC SQL INCLUDE SQLCA;
     int VALIDATE(cmd,cmdlen,smg,smglen,query)
      char *cmd;   /* Строка,содержащая имя и параметр подсоединяемой прог-
                      раммы в шаге триггера,активизирующего подсоединяемую
                      программу.*/
      int *cmdlen; /* Указатель длины "cmd".*/
      char *msg;   /* Сообщение о неудаче,определенное для шага триггера,
                      "включающего" подсоединяемую программу.*/
      int *msglen;  /* Указатель длины "msg".*/
      int *query;  /* Указатель флага состояния.Если подсоединяемая програм-
                      ма была включена из триггера post-query,флаг равен 1
                      (TRUE); иначе - 0 (FALSE).*/
     {
     ...
     return(SUCCESS); /* Успешное завершение.*/
     ...
     return(FAILURE); /* Неудачное завершение.*/
     ...
     return(FATAL-ERR); /* Фатальная ошибка.*/
     }

               EСоглашения по передаче параметров в КОБОЛеF
     Описанная в примере 2 программа показывает соглашения по передаче пара-
метров для подсоединяемых программ,написанных на Коболе.Примечание для прог-
раммирующих на VMS COBOL: Фраза GIVING RETURN-CODE должна добавляться в опе-
ратор PROCEDURE DIVISION для того,чтобы проинформировать компиллятор о возв-
рате значения.
                               EПример 2F
     ...
     DATA DIVISION.
     WORKING-STOREGE SECTION.

     01 RETURN-CODE PIC S9(9) COMP.

 * Переменные подсоединяемой программы,указанные в командах
 * EXEC SQL или EXEC IAF,м.б. объявлены в секции
 * DECLARE.
     EXEC SQL BEGIN DECLARE SECTION;
     01 I1      PIC S9(4) COMP.
     01 C1      PIC X(64).
     01 F1      COMP-1.
       EXEC SQL END DECLARE SECTION;
 * Эта команда Pro*COBOL определяет символы,ипользуемые для
 * интерфейса с SQL*Forms.
     EXEC SQL INCLUDE SQLCA;
     LINKAGE SECTION.
 * Строка,содержащая имя подсоединяемой программы и параметр.
     01 CMD-LINE   PIC X(80).
 * Длина значения CMD-LINE.
     01 CMD-LINE-LEN PIC S9(9) COMP.
 * Сообщение о неудаче,определенное в шаге триггера,кото-
 * рый "включает" подсоединяемую программу.
     01 ERR-MSG       PIC X(80).
 * Длина значения ERR-MSG.
    01 ERR-MSG-LEN PIC S9(9) COMP.
 * Если подсоединяемая программа активизирована из триггерa
 * post-query,1; иначе 0.
     01 IN-QUERY   PIC S9(9) COMP.
     PROCEDURE DIVISION
      USING CMD-LINE CMD-LINE-LEN ERR-MSG ERR-MSG-LEN
      IN QUERY.
      ...
      MOVE SQL-IAPXIT-SUCCESS TO RETURN-CODE.
      EXIT PROGRAM.
      ...
      MOVE SQL-IAPXIT-FAILURE TO RETURN-CODE.
      EXIT PROGRAM.
      ...
      MOVE SQL-IAPXIT-FATALERROR TO RETURN-CODE.
      EXIT PROGRAM.
      ...

              EСоглашения по передаче параметров в ФОРТРАНеF
     Описанная в примере 3 программа показывает соглашения по передаче пара-
метров для подсоединяемых программ,написанных на ФОРТРАНе.
                                 EПример 3F
     C COMND: Строка,содержащая имя подсоединяемой программы и параметр
     C LCOMND: Длина значения COMND.
     C ERROR: Сообщение о неудаче,определенное в шаге триггера,
     C который "включает" подсоединяемую программу.
     C LERROR: Длина значения ERROR.
     C INQRY: Если подсоединяемая программа активизирована из
     C     триггера post-query,1(TRUE); иначе 0(FALSE).
        FUNCTION VALID8(COMND,LCOMND,ERROR,LERROR,INQRY)
        LOGICAL*1 COMND,ERROR
        INTEGER LCOMND,LERROR,INQRY
        ...
     C Переменные подсоединяемой программы,указанные в командах
     C EXEC SQL или EXEC IAF,м.б. объявлены в секции DECLARE.
        EXEC SQL BEGIN DECLARE SECTION
        INTEGER I1
        CHARACTER*1 C1
        REAL*4 F1
        EXEC SQL END DECLARE SECTION
     C Эта команда Pro*FORTRAN определяет символы,ипользуемые
     C для интерфейса с SQL*Forms.
        EXEC SQL INCLUDE SQLCA
        ...
        VALID8 = IAPSUC
        RETURN
        ...
        VALID8 = IAPFAI
        RETURN
        ...
        VALID8 = IAPFTL
        RETURN
        ...
        END

                 EСоглашения по передаче параметров в ПЛ/1F
     Описанная в примере 4 программа показывает соглашения по передаче пара-
метров для подсоединяемых программ,написанных на ПЛ/1.

                            EПример 4F
     VALIDATE:
     PROCEDURE(CMD_LINE,CMD_LINE_LEN,ERR_MSG,ERR_MSG_LEN,IN_QUERY)
      RETURNS (BINARY FIXED(31));
     /* Строка,содержащая имя подсоединяемой программы и параметр.*/
      DECLARE CMD_LINE CHARACTER(80);
      /* Длина значения CMD_LINE.*/
      DECLARE CMD_LINE_LEN BINARY FIXED(31);
     /* Сообщение о неудаче,определенное в шаге триггера,кото-
     рый "включает" подсоединяемую программу.*/
      DECLARE ERR_MSG CHARACTER(80);
     /* Длина значения ERR_MSG.*/
      DECLARE ERR_MSG_LEN BINARY FIXED(31);
   /* Если подсоединяемая программа активизирована из триггера post-query,1;
      иначе 0.*/
      DECLARE IN_QUIRY BINARY FIXED(31);
     /* Переменные подсоединяемой программы,указанные в командах
     EXEC SQL или EXEC IAF,м.б. объявлены в секции DECLARE.*/
      EXEC SQL BEGIN DECLARE SECTION;
      DECLARE I1 BINARY FIXED(31);
      DECLARE C1 CHARACTER(64) VARYING;
      DECLARE F1 DECIMAL FLOAT(6);
      EXEC SQL END DECLARE SECTION.
     /* Эта команда Pro*PL/I определяет символы,ипользуемые для
     интерфейса с SQL*Forms.*/
        EXEC SQL INCLUDE SQLCA;
        ...
        RETURN(SQL_IAPXIT_SUCCESS);
        ...
        RETURN(SQL_IAPXIT_FAILURE);
        ...
        RETURN(SQL_IAPXIT_IAPFATALERROR);
        ...
        END VALIDATE;

               EСоглашения по передаче параметров в ПАСКАЛеF
     Описанная в примере 5 программа показывает соглашения по передаче пара-
метров для подсоединяемых программ,написанных на ПАСКАЛе.

                             EПример 5F
     Function VALIDATE(
     (* Строка,содержащая имя подсоединяемой программы и параметр.*)
             Cmd_line:  Array[80] of Char;
     (* Длина значения Cmd_line.*)
             Cmd_line_len:Integer;
     (* Сообщение о неудаче,определенное в шаге триггера,кото-
     рый "включает" подсоединяемую программу.*)
             Err_msg:   Array[80] of Char;
     (* Длина значения Err_msg.*)
             Err_msg_len: Integer;
     (* Если подсоединяемая программа активизирована из триггера
      post-query,1; иначе 0.*)
             In_query:  Integer) : Integer;

     EXEC SQL INCLUDE ORATYPE;
     (* Переменные подсоединяемой программы,указанные в командах
     EXEC SQL или EXEC IAF,м.б. объявлены в секции DECLARE.*)
     EXEC SQL BEGIN DECLARE SECTION;
      c1: Array Varying [64] of Char;
      f1: Real;
     EXEC SQL END DECLARE SECTION;
     (* Эта команда Pro*Pascal определяет символы, ипользуемые
     для интерфейса с SQL*Forms.*)
     EXEC SQL INCLUDE SQLCA;
     Begin
      ...
      return(SQL_IAPXIT_SUCCESS);
      ...
      return(SQL_IAPXIT_FAILURER);
      ...
      return(SQL_IAPXIT_FATALERR);
      ...
     End;

     EКонстанты IAP,определяемые только если присутствует EXEC IAFF
     Процессор определяет символьные константы,начинающиеся с IAP (например,
IAPSUCC,IAPFAIL и IAPFTL в Си),только если подсоединяемая программа содержит
команды EXEC IAF.Если подсоединяемая программа не содержит команды EXEC IAF,
вы должны определить эти константы самостоятельно.

         EИспользование SQLIEM для отображения сообщений об ошибкеF
     Указатель SQLIEM задает сообщение,которое SQL*Forms будет отображать,
если данный шаг триггера завершится неудачно или,если при выполнении шага
триггера возникла фатальная ошибка и нажимается клавиша [Display Error].
Это сообщение заменяет обычное сообщение об ошибке (если оно определено).
     Вызовы SQLIEM в Си,КОБОЛе,ФОРТРАНе,ПАСКАЛе,ПЛ/1 показа ны в примерах
6-11.
     Примечаниe для программирующих в VM/CMS: для разных главных языков
SQLIEM при вызовах называется по-разному:
        * SQ0IEM для КОБОЛа
        * SQ1IEM для ФОРТРАНа
        * SQ2IEM для Си
        * SQ3IEM для ПЛ/1
        * SQ4IEM для ПАСКАЛя
     Примечаниe для программирующих в VMS FORTRAN: обычно,чтобы передать для
функции строку TYPE CHARACTER,VMS FORTRAN использует нестандарный метод
(скорее посредством описателя,нежели с помощью указателя).Так,псевдо-функция
%REF должна применятьтся для любого строкового параметра,передаваемого для
функции SQL*Forms.Это показано в примере 9.

                               EПример 6F
     char *exit_message:   /* Указатель на сообщение.*./
     int exit_message_len;  /* Длина сообщения.*/
     ...
     exit_message = "Invalid Exit Parameter";
     exit_message_len = strlen(exit-message);
     sqliem(exit_message,&exit_message_len);
     ...
                               EПример 7F
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01 EXIT-MESSAGE PIC X(80).
     01 EXIT_MESSAGE-LEN  PIC S9(9) COMP.
     ...
     PROCEDURE DIVISION...
     ...
     * Вызвать SQLIEM с сообщением и его длиной в качестве параметров
      MOVE "Invalid Exit Parameter" TO EXIT-MESSAGE.
      MOVE 22 TO EXIT-MESSAGE-LEN.
      CALL "SQLIEM" USING EXIT-MESSAGE EXIT-MESSAGE-LEN.
      ...
                              EПример 8F
     FUNCTION...
        ...
     C XITERM - СООБШЕНИЕ ОБ ОШИБКЕ; XITERL - ДЛИНА
        CHARACTER*80 XITERM
        INT XITERL
        ...
     C Вызвать SQLIEM с сообщением и его длиной в качестве параметров
        XITERM = 'Invalid Exit Parameter'
        XIERL = 22
        CALL SQLIEM(XITERM,XITERL)
        ...
                              EПример 9F
     FUNCTION...
        ...
     C XITERM - СООБШЕНИЕ ОБ ОШИБКЕ; XITERL - ДЛИНА
        CHARACTER*80 XITERM
        INT XITERL
        ...
     C Вызвать SQLIEM с сообщением и его длиной в качестве параметров
        XITERM = 'Invalid Exit Parameter'
        XIERL = 22
        CALL SQLIEM(%REF(XITERM),%REF(XITERL))
        ...
                             EПример 10F
     ...
     DECLARE EXIT_MSG       CHARACTER(80);
     DECLARE EXIT_MSG_LEN     BINARY FIXED(31);
     ...
     /* Вызвать SQLIEM с сообщением и его длиной в качестве параметров.*/
     EXIT_MSG = 'Inalid Exit Paramter';
     EXIT_MSG_LEN = LENGTH(EXIT_MSG);
     SQLIEM(EXIT_MSG,EXIT_MSG_LEN);
     ...
                             EПример 11F
     ...
     Var
        Exit_msg:       Array Varying [80] of Char;
        Exit_msg_len:     Integer;
     ...
     Begin
     ...
     Exit_msg = 'Invalid Exit Parameter';
     Exit_msg_len = len(Exit_msg);
     SQLIEM(Exit_msg,Exit_msg_len);
     ...
     End;

                 EЧтение и запись значений поля формыF
                    EСчитывание значения поля формыF
     Работая с РСС,вы можете использовать только одну,совместимую со всеми
главными языками,процедуру считывания значения поля.
     Переменная,для которая будет принимать значение,д.б. объявлена в секции
DECLARE.Секция DECLARE м.б. использована в любом месте исходной программы,
где объявляются переменные.Секции DECLARE для каждого языка показаны ранее в
примерах 1-5 данного приложения.
     SQL-команда EXEC IAF GET используется для считывания значения поля SQL*
Forms в переменную подсоединяемой программы.Ее формат:

                       EВ Си,ПАСКАЛе и ПЛ/1:F
     EXEC IAF GET  field1,filed2,...,fieldn
     INTO      :var1,:var2,...,:varn;

                            EВ КОБОЛе:F
     EXEC IAF GET  field1,filed2,...,fieldn
      INTO    :var1,:var2,...,:varn
      END-EXEC.

                           EВ ФОРТРАНе:F
     EXEC IAF GET  field1,filed2,...,fieldn
      INTO    :var1,:var2,...,:varn

     Каждое "field" идентифицирует поле в форме с помощью его имени.Каждая
"var" идентифицирует переменную подсоединяемой программы.Когда выполняется
команда EXEC IAF GET,значение каждого  "field" конкретной записи считывается
в соответсвующую "var".
      Каждая "var" должна предваряться двоеточием (:).
      Имя поля можно совмещать с именем блока,например: EMP.EMPNO
     Если имя поля не уточняется,поле должно находится в контексте блок
(один из триггеров которого вызвал подсоединяемую программу пользователя).
     Все поля формы представлены в формате строк символов.Когда это необхо-
димо,EXEC IAF GET пытается преобразовать тип поля к типу соответствующей пе-
ременной подсоединяемой программы по принятым для прекомпилятора правилам.
     Например,команды EXEC IAF GET (данные в этом приложении) считывают зна-
чения полей ENAME и EMPNO из блока с именем EMP в переменные "i1" и "c1" по-
дсоединяемых программ.
     Во время выполнения поле м.б. выбрано посредством присвоения его имени
строковой переменной (например,"stirng") и обращения к полю как ":string".
Например,следующие фрагменты программы считывают значение поля NAME блока
EMP в переменную 'i2' подсоединяемой программы:

                                 EВ Си:F
     EXEC SQL BEGIN DECLARE SECTION;
     VARCHAR *fieldref;
     ...
     EXEC SQL END DECLARE SECTION;
     ...
     fieldref.len = strlen(strcopy(fieldref.arr,"EMP.NAME));
     EXEC IAF GET :fieldref INTO :i2;

                                EВ КОБОЛе:F
     EXEC SQL BEGIN DECLARE SECTION.
     01  FIELD-REF    PIC X(10) VARYING.
     ...
     EXEC SQL END DECLARE SECTION
     ...
     MOVE "EMP.NAME" TO FIELD-REF-ARR.
     MOVE 8 TO FIELD-REF-LEN.
     EXEC IAF GET :FIELD-REF INTO :I2
     END-EXEC.

                               EВ ФОРТРАНе:F
     EXEC SQL BEGIN DECLARE SECTION
     VARCHAR*10 FLDREF,FLDLEN,FLDARR
     ...
     EXEC SQL END DECLARE SECTION
     ...
     FLDARR = 'EMP.NAME'
     FLDLEN = 8
     EXEC IAF GET :FLDREF INTO :I2

                                EВ ПЛ/1:F
     EXEC SQL BEGIN DECLARE SECTION;
     DECLARE FIELDREF CHARACTER(10) VARYING;
     ...
     EXEC SQL END DECLARE SECTION;
     ...
      FIELDREF = 'NAME.EMP';
      EXEC IAF GET :FIELDREF INTO :I2;

                               EВ ПАСКАЛе:F
     EXEC SQL BEGIN DECLARE SECTION;
     Fieldref: Varying [10] of Char;
     ...
     EXEC SQL END DECLARE SECTION;
     ...
     Fieldref = 'NAME.EMP';
     EXEC IAF GET :FIELDREF INTO :i2;

     Обратите внимание на использование типа данных CHARACTER  ...VARYING в
примере для ПЛ/1,Varying - для ПАСКАЛя и псевдо-типа данных VARCHAR в других
примерах.Переменная,объявленная как VARYING или VARCHAR,имеет поле такой
длины,которая делает его пригодным для хранения поля с длиной более корот-
кой,чем объявленная.Поле,указанное во операторах EXEC IAF и EXEC SQL,м.б.
создано с данным типом переменной или с типом переменной фиксированной дли-
ны,которая будет дополнена до своей полной длины пробелами.В команде EXEC
IAF GET могут одновременно присутсвовать как указатели поля,так и явно за-
данные имена поля,но не для случая обращения к одному полю.Например,поле в
операторе EMP.:fieldref (где filedref - указатель поля,EMP - имя формы) за-
дано некорректно.

                    EСчитывание значений из таблицыF
     Процедура считывания значения из таблицы подобна процедуре считывания
поля из формы.Но при этом вместо команды EXEC IAF GET вам необходимо исполь-
зовать команду EXEC SQL SELECT.
     При считывании значения из столбца таблицы переменная подсоединяемой
программы д.б. объявлена в секции DECLARE точно так же,как если бы она испо-
льзовалась для считывания значения из поля формы; правила для оформления се-
кции DECLARE те же самые.
             Формат команды EXEC SQL SELECT следующий:

                      EВ Си,ПЛ/1 и ПАСКАЛе:F
     EXEC SQL SELECT column1,column2,...columnx
      INTO :var1,:var2,...:varn
      FROM table
      WHERE condition;

                             EВ КОБОЛе:F
     EXEC SQL SELECT column1,column2,...сolumnx
      INTO :var1,:var2,...:varn
      FROM table
      WHERE condition
      END-EXEC.

                            EВ ФОРТРАНе:F
     EXEC SQL SELECT column1,сolumn2,...сolumnx
     X INTO :var1,:var2,...:varn
     X FROM table
     X WHERE condition

     Параметры "table" и "column1,column2,...,columnx" идентифицируют табли-
цу и столбец (столбцы),из полей которых будут считаны значения.Каждая "var"
является переменной подсоединяемой программы,которой передается значение по-
ля соотвествующего столбца ("var1" принимает значение из поля столбца
"column1",и т.д.).
     Параметр "condition" является логическим условием,по которому выбирает-
ся строка таблицы,из которой будут считываться поля.В большинстве случаев
условие должно определять максимум одну строку таблицы.Если с помощью усло-
вия выбирается более одной строки,в переменные будет считываться значение
одной из строк,но не существует надежного способа предсказать,из какой имен-
но.Если с помощью "condition" не выбирается ни одной записи,при выполнении
команды EXEC SQL SELECT произойдет окончание выборки по ошибке; подробности
этого процесса обсуждаются ниже в данном приложении в разделе "Обработка
ошибок и команда EXEC SQL WHENEVER".
     Например,следующая команда считывает значение из столбца с именем NAME
таблицы EMP в переменную "c2" подсоединяемой программы.Значение считывается
из строки,чей ROWID (идент.строки) равен значению переменной "srow" в подсо-
единяемой программе:
                                 EВ Си:F
     EXEC SQL BEGIN DECLARE SECTION;
     char srow[31];
     ...
     EXEC SQL END DECLARE SECTION;
     ...
     EXEC SQL SELECT NAME
     INTO :12 FROM EMP WHERE ROWID=:srow;

                                EВ КОБОЛе:F
     EXEC SQL BEGIN DECLARE SECTION;
     01  SROW      PIC X(30).
     ...
     EXEC SQL END DECLARE SECTION.
     ...
     EXEC SQL SELECT NAME
      INTO :I2 FROM EMP WHERE ROWID=:SROW
      END-EXEC.

                              EВ ФОРТРАНе:F
     EXEC SQL BEGIN DECLARE SECTION
     CHARACTER*30 SROW
     ...
     EXEC SQL END DECLARE SECTION
     ...
     EXEC SQL SELECT NAME
      INTO :I2 FROM EMP WHERE ROWID=:SROW

                              EВ ПЛ/1:F
     EXEC SQL BEGIN DECLARE SECTION;
     DECLARE SROW CHARACTER(30);
     ...
     EXEC SQL END DECLARE SECTION
     ...
     EXEC SQL SELECT NAME
      INTO :I2 FROM EMP WHERE ROWID=:SROW;

                             EВ ПАСКАЛеF
     EXEC SQL BEGIN DECLARE SECTION;
     Srow: Array Varying [30] of Char;
     ...
     EXEC SQL END DECLARE SECTION;
      ...
      EXEC SQL SELECT NAME
          INTO :i2 FROM EMP WHERE ROWID=:Srow;

     Эти примеры показывают общий метод,обеспечивающий выбор с помощью EXEC
SQL SELECТ ровно одной строки таблицы за счет использования фразы WHERE,ко-
торая выбирает желаемую строку по ее ROWID (или соответствующую запись блока
формы).
     Так как длина ROWID является фиксированной (30 символов),объявления
VARYING или VARCHAR не обязательны.(В примере,относящемся к Си,"sraw" объяв-
ляется строкой символов,состоящей из 31 знака,чтобы выделить пространство,
используемое стандарными функциями языка Си для хранению 30 -символьной ст-
роки с обычным для Си нулевым ограничителем.Такой прием является обычным для
Си,но не нужно его применять для Pro*С или SQL.)
     Другим способом обеспечения гарантии выбора с помощью команды SELECT
только одной строки является выбор столбца,чье значение уникально,- либо по-
тому,что для этого столбца задан ORACLE-индекс с параметром UNIQUE,или же
потому,что его уникальность обеспечивается первичным ключом формы.В отличие
от метода,использующего идентификаторы строк,этот метод гарантирует,что ко-
манда EXEC SQL SELECT будет производить выборку  максимум одной записи; с
его помощью можно не выбрать ни одной записи; при этом произойдет окончание
выборки по ошибке.

                       EЗапись значений в поля формыF
     Процедура записи значения в поле подобна процедуре считывания значения
из поля.Переменная подсоединяемой программы,используемая в качестве источни-
ка такого значения,д.б. объявлена в секции DECLARE.
     Значения полей формы могут записываться с помощью SQL-команды EXEC IAF
PUT.Формат команды следующий:
                         EВ Си,ПЛ/1 и ПАСКАЛе:F
     EXEC IAF PUT поле1,поле2,...,полеn
        VALUES ( значение1,значение2,...,значениеn );

                                EВ КОБОЛе:F
     EXEC IAF PUT поле1,поле2,...,полеn
        VALUES ( значение1,значение2,...,значениеn )
        END-EXEC.

                              EВ ФОРТРАНе:F
     EXEC IAF PUT поле1,поле2,...,полеn
     X   VALUES ( значение1,значение2,...,значениеn )

     Каждое "поле" идентифицирует поле формы.Каждое "значение" указывает
значение.Когда команда EXEC IAF PUT выполнена,каждое "значение" записывается
в соответствующее "поле" контекстной записи.
     "Значение" м.б. константой или указателем переменной подсоединяемой
программы пользователя:
 * NUMBER-константа представляет собой число с 10-ной точкой или без нее.
 * Константа типа CHAR или DATE представляет собой заключенную в апострофы
   строку (не ставить кавычки,даже если они требуются по правилам главного
   языка - потому,что это команда SQL,а не оператор главного языка).
 * Ссылка к переменной подсоединяемой программы предваряется двоеточием,как
   в EXEC IAF GET.Например,следующие команды записывают значения каждого из
   3 типов в поля EMPNO,NAME,и MGR блока EMP:
                             EВ Си и ПАСКАЛе:F
     EXEC IAF PUT EMP.EMPNO,EMP.NAME,EMP.MGR
      VALUES ( 3572,'0''BRIEN',:i1 )

                               EВ КОБОЛе:F
     EXEC IAF PUT EMP.EMPNO,EMP.NAME,EMP.MGR
      VALUES ( 3572,'0''BRIEN',:I1 )
      END-EXEC.

                              EВ ФОРТРАНе:F
     EXEC IAF PUT EMP.EMPNO,EMP.NAME,EMP.MGR
     X VALUES ( 3572,'0''BRIEN',:I1 )

                                EВ ПЛ/1:F
     EXEC IAF PUT EMP.EMPNO,EMP.NAME,EMP.MGR
      VALUES ( 3572,'0''BRIEN',:I1 );

     Как и в EXEC IAF GET,поле можно выбрать во время выполнения с помощью
присвоения его имени строке и обращения к полю по ":строка".

                                EВ Си:F
     EXEC SQL BEGIN DECLARE SECTION;
     VARCHAR *fieldref:
     ...
     EXEC SQL END DECLARE SECTION;
     ...
     fieldref.len = strlen( strcpy(fieldref.arr,"NAME.EMP") );
     EXEC IAF PUT :fieldref VALUES ( :i2 );

                              EВ КОБОЛе:F
     EXEC SQL BEGIN DECLARE SECTION.
     01  FIELD-REF    PIC X(10) VARYING.
     ...
     EXEC SQL END DECLARE SECTION.
     ...
     MOVE "NAME.EMP" TO FIELD-REF-ARR.
     MOVE 8 TO FIELD-REF-LEN.
     EXEC IAF PUT :FIELD-REF VALUES ( :I2 ) END-EXEC.

                            EВ ФОРТРАНе:F
     EXEC SQL BEGIN DECLARE SECTION
     VARCHAR*10 FLDREF,FLDLEN,FLDARR
     ...
     EXEC SQL END DECLARE SECTION
      ...
     FLDARR = 'NAME.EMP'
     FLDLEN = 8
     EXEC IAF PUT :FLDREF VALUES ( :I2 )

                              EВ ПЛ/1F

KOAP Open Portal 2000