СУБД Oracle для разработчиков. Forms and Reports 6i-10g
Обзор PL/SQL в Oracle Forms 6i
Сергеенко С.В.
Использование циклов
В ваших приложениях вам не раз придется исполнять какую-то группу операторов неоднократно. Повторять операторы можно двумя способами: указние конкретного числа проходов в цикле или выполнять цикл до встречи с некоторым условием сравнения, покаусловия не будет истинно.Поскольку Oracle Forms содержит встроенный PL/SQL, то, следовательно, и циклы в Forms будут такого же типа как и в PL/SQL:
·LOOP-EXIT
·WHILE-LOOP
·FOR-LOOP
LOOP-EXIT – это один из самых простых циклов PL/SQL. Ключевое слово LOOP указывает на начало повторяемого программного блока, а END LOOP на его конец. Ключевое слово EXIT , указываемое отдельно, означает, что цикл нужно прервать,
а ключевое слово EXIT WHEN – что предлагаемый оператор сравнения нужно проверить на необходимость завершения выполнения операторов. Рассмотрим пример с применением такого цикла:
для началасоздайте таблицуEXEM1:
create table Exem1 (SUM number) nologging;
теперь пример:
Declare
i number:=0;
Begin
LOOP
i:=C_ount+1
insert into EXEM1(SUM)
values (i);
IF i=10 THEN
EXIT;
end if;
end loop;
end;
После выполнения этого цикла в таблицу EXEM1 будет вставлено 10 записей, причем здесь наглядно видно, что как только наше условие будет истинно, то есть, значениесчетчика i будет равным 10 – цикл прервется.
Теперь рассмотрим этот же пример, только с использованием оператора EXIT-WHEN:
Declare
i number:=0;
Begin
LOOP
i:=C_ount+1;
insert into EXEM1(SUM)
values (i);
EXIT WHEN i=10;
end loop;
end;
Из этого примера видно, что такая конструкция в отличии от предыдущей дает возможность разработчику писать менее громоздкий код.
WHILE-LOOP– цикл этого типапохож на цикл с условием LOOP-EXIT WHEN, разница заключается в том, что в WHILE-LOOP проверка условия выхода осуществляется в начале цикла. Если сравнивать два этих цикла, то по гибкости, конечно, выигрывает
LOOP-EXIT, т.к. позволяетуказывать условие EXIT в любом месте цикла, а если сравнивать поэлегантности и краткости оформления кода, то WHILE-LOOP выигрывает. Рассмотрим тот же самый пример, что и в предыдущем случае, только с использованиемконструкции
WHILE-LOOP:
Declare
i number:=0;
Begin
while i<=10 LOOP
i:=C_ount+1;
insert into EXEM1(SUM)
values (i);
end loop;
end;
В этом примере мы еще больше упростили наш цикл, т.к. не использовали оператор EXIT.
FOR_LOOP – этот цикл отличается от двух других т.к. позволяет указать конкретное число раз выполнения программы до ее прерывания. Данная циклическая конструкция состоит из счетчика и диапазона циркуляциицикла. Счетчик в операторах FOR-LOOP является встроенным и автоматически увеличивает значение на единицу. Диапазон циркуляциии определяют нижняя и верхняя граница, причем границы
должны иметь целочисленный тип. Нижняя граница дипазона циркуляции цикла может начинаться не только с единицы, но и с любого другого целого числа.
Для примера создадим таблицу EXEM1 с одним столбцом типа number - SUM, который содержит различные числовые значения. Теперь выполним цикл:
DECLARE
C_OUNT NUMBER;
BEGIN
for i in 1..10 loop
insert into EXEM1(SUM)
values (i);
C_OUNT:=C_OUNT+i;
end loop;
SELECT C_OUNT INTO :block_name.item_name from DUAL;
end;
После выполнения этого цикла в таблицу EXEM1 будет вставлено 10 записей с значением от 1 до 10, а затем результат суммирования значений, вставленных записей, будет выведен в элемент формы :block_name.item_name.В
рассмотреном нами цикле, встроенным счетчиком будет переменная i, а диапазоном циркуляции будет интервал от 1 до 10, где 1 – это нижняя граница диапазона, а 10 – верхняя. Если рассмотреть пример, который мы приводили в двух предыдущих случаях, только с применением операторов FOR-LOOP, то вы увидете, что применение этой конструкции делает кодеще более элегантнее:
Declare
i number:=0;
Begin
for i in 1..10 LOOP
insert into EXEM1(SUM)
values (i);
end loop;
end;
FOR_LOOP также позволяет исполнять цикл в другом направлении, с помощью оператора REVERSE, причем при изменении направления цикла вам не надо как-то иначе задавать границы диапазона, т.к. Oracle сделает это за вас:
Declare
i number:=0;
Begin
for i in REVERSE 1..10 LOOP
insert into EXEM1(SUM)
values (i);
end loop;
end;
Существуют также операторы FOR-LOOP для работы с курсорами, которые будут рассмотренны в разделе описания курсоров.
И в заключение хочу добавить, что Oracle Forms позволяет создавать циклические конструкции любого уровня вложенности. Поэтому, рассмотренные нами конструкции тоже могут быть вложенными.
Условное управление
Условным управлением называется оператор IF_THEN (если-то), который говорит о том, что при истинности условия или наоборот, нужно выполнить следущий программный блок.
Использование этого оператора позволяет разработчику структурировать код программы таким образом, что определенные операторы будут или не будут выполняться – это определяется достоверностью операции сравнения. Причем логика этой конструкции следущая: если (IF) сравнение истинно, тогда (THEN) выполнить следующее. В PL/SQL существуют еще две дополнительные конструкции ELSE (иначе) и ELSIF (иначе если). Логика
оператора ELSE: “в противном случае сделать то, что указано в конструкции ELSE”, а логика оператораELSEIF: “в противном случае, если...”. Оператор ELSIF позволяет вам исключить дополнительное вложение оператора IF внутрь конструкции ELSE, поэтому позволяет реализовать операцию взаимоисключения более четко. Приведем простой пример:
WHEN_NEW_FORM_INSTACE:
BEGIN
IF TO_CHAR (TO_DATE(SYSDATE, 'DAY')='SATURDAY' or TO_CHAR (TO_DATE(SYSDATE, 'DAY')='SUNDAY'
message ('Сегодня '||TO_CHAR (SYSDATE,'DAY')||'удачного рабочего дня');
end if;
end;
Здесь перед запуском формы проверется выходной день сегодня или рабочий, если условие истинно, то есть сегодня выходной, то запретить какие либо операции , связанные с манипуляцией данных, если же условие ложно, то в строке состояния появится сообщение: “Сегодня понедельник удачного рабочего дня”. Теперь рассмотрим пример с использованием оператора ELSE:
Как видим, построенная конструкция IF-THEN с помощью оператора ELSIF менее грамоздка и более понятна.
И в заключение рассмотрим пример, в котором используются как условныетак и итеративные операторы:
DECLARE
OriPos number;
BEGIN
OriPos := TO_NUMBER(:System.Trigger_Record);
First_Record;
LOOP
IF (:System.Last_Record = 'TRUE') THEN
Go_Record(OriPos);
EXIT;
ELSE
Next_Record;
END IF;
END LOOP;
END;
Последовательно управление
В PL/SQL существует оператор, который называется – метка (label). Метка (goto) – это последовательность символов, отмечающая некоторый исполняемый блок и используется для выхода из условной структуры, обработчика исключительных ситуаций или программного блока. Оператор GOTO дает возможность перейти из места его указания в программенепосредственно к метке.
LOOP
IF (:System.Last_Record = 'TRUE') THEN
goto first_rec;
ELSE
Next_Record;
END IF;
END LOOP;
<<first_rec>>
First_record;
END;
Ограничения на использование GOTO :
·нельзя разместить метку перед неисполняемым оператором, например перед if, end loop и т.д. Если же ва всетаки необходимо разместить метку там, где нет исполняемого оператора, вам следует
воспользоваться ключевым словом NULL, который как известно не производит никаких действий, но при этом удовлетворяет требованиям предъявляемых к меткам. Для примера возьмем кусочек из предыдущей программы:
LOOP
IF (:System.Last_Record = 'TRUE') THEN
goto first_rec;
.......
<<first_rec>>
END;
Обратите внимание, что между меткой и оператором завершения (end) нет исполняемого оператора, поэтому такое объявление метки вызовет ошибку. Для того чтобы избежать этой ошибки достаточно написать ключевое слово NULL:
LOOP
IF (:System.Last_Record = 'TRUE') THEN
goto first_rec;
.......
<<first_rec>>
NULL;
END;
·Оператор GOTO используется только для выхода из структуры, но не для входа в нее. Приведем пример такого объявления, все из того же программного блока:
goto first_rec;
LOOP
IF (:System.Last_Record = 'TRUE') THEN
<<first_rec>>
ELSE
Next_Record;
END IF;
END LOOP;
First_record;
END;
Совет: Старайтесь как можно более элегантней оформлять свой код, с помощью выше указаных операторов для повышения читабельности вашей программы. Чтобы ваш прогаммный блок имел вид осмысленной структуры.
Все комментарии и вопросы прошу присылать по адресу sqaimes@mail.ru