Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

СУБД 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'

THEN

set_block_property('Block1',update_allowed, property_false);

set_block_property('Block1',insert_allowed, property_false);                

set_block_property('Block1',delete_allowed, property_false);

ELSE

message ('Сегодня  '||TO_CHAR (SYSDATE,'DAY')||' удачного рабочего дня');

end if;

end;

Здесь перед запуском формы проверется выходной день сегодня или рабочий, если условие истинно, то есть сегодня выходной, то запретить какие либо операции , связанные с манипуляцией данных, если же условие ложно, то в строке состояния появится сообщение: “Сегодня понедельник удачного рабочего дня”. Теперь рассмотрим пример с использованием оператора ELSE:

Declare

  but_no  Varchar2(1) := :System.Mouse_Button_Pressed ;

Begin

  If but_no = '1' Then

     Message('Нажата левая кнопка');

  Else  If LN$Btn = '2' Then

     Message('Нажата правая кнопка' );

  End if ;

End if;

End ;

Теперь рассмотрим тот же случай только с использованием оператора ELSIF:

Declare

  but_no  Varchar2(1) := :System.Mouse_Button_Pressed ;

Begin

  If but_no = '1' Then

     Message('Нажата левая кнопка');

  ELSIF LN$Btn = '2' Then

     Message('Нажата правая кнопка' );

  End if;

End ;

Как видим, построенная конструкция 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


В избранное