Опубликован: 25.09.2009 | Уровень: специалист | Доступ: платный
Лекция 2:

PL/SQL в Oracle Forms. Управляющие структуры. Глобальные переменные и параметры

< Лекция 1 || Лекция 2: 123 || Лекция 3 >

Системные переменные и константы

Системные переменные - это переменные сессии Oracle Forms. Как только вы запускаете приложение, вам становятся доступны все его переменные окружения, выполнения и внутреннего состояния. Системные переменные, их имена и типы не привязаны к какому-либо объекту конкретно, они лишь передают текущее состояние или значение объекта, поэтому системная переменная - это, скорее, ссылка на текущее состояние приложения, элемента или события. Практически все системные переменные имеют тип данных VARCHAR и поэтому могут возвращать различные типы данных, такие как число, дата, строка. Системные переменные - это не только путь к написанию правильного и "гибкого" кода, это еще и огромный шаг к написанию переносимых и независимых программных единиц. Для наглядного примера напишем триггер, в котором нам нужно будет определить статус блока и, если блок находится в режиме CHANGED, сохранить изменения.

  1. Пример с использованием системной переменной:
    If :SYSTEM.BLOCK_STATUS = 'CHANGED' Then
    Commit_Form ; 
    End if ;
  2. Пример без использования системной переменной:
if get_block_property('block_name', status)='CHANGED' then 
 Commit_Form; 
end if;

Если сравнивать эти два примера, то основной и самой существенной разницей между ними будет отсутствие в первом имени блока, статус

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

Все системные переменные, за исключением четырех, являются Read_Only, то есть "только для чтения". Ниже приведена табл. 16.2, в которой перечислены все основные системные переменные.

Таблица 2.2. Основные системные переменные
Системная переменная
SYSTEM.BLOCKSTATUS
SYSTEM.COORDINATIONOPERATION
SYSTEM.CURRENT BLOCK
SYSTEM.CURRENT DATETIME
SYSTEM.CURRENT ITEM
SYSTEM.CURRENT FORM
SYSTEM.CURRENT VALUE
SYSTEM.CURSORBLOCK
SYSTEM.CURSORITEM
SYSTEM.CURSORRECORD
SYSTEM.CURSORVALUE
SYSTEM.CUSTOMITEMEVENT
SYSTEM.CUSTOMITEMEVENTPARAMETERS
SYSTEM.DATE THRESHOLD
SYSTEM.EFFECTIVEDATE
SYSTEM.EVENTWINDOW
SYSTEM.FORMSTATUS
SYSTEM.LASTQUERY
SYSTEM.MESSAGELEVEL
SYSTEM.MODE
SYSTEM.MOUSEBUTTONPRESSED
SYSTEM.MOUSEBUTTONSHIFTSTATE
SYSTEM.MOUSECANVAS
SYSTEM.MOUSEFORM
SYSTEM.MOUSERECORD
SYSTEM. MOUSEWIN DOW
SYSTEM.MOUSEXPOS
SYSTEM. MOUSEYPOS
SYSTEM.RECORDSTATUS
SYSTEM.SUPPRESSWORKING
SYSTEM.TRIGGER BLOCK
SYSTEM.TRIGGERITEM
SYSTEM.TRIGGERRECORD
SYSTEM.MASTERBLOCK
SYSTEM.TABNEWPAGE
SYSTEM.TABPREVIOUSPAGE

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

SYSTEM.BLOCK_STATUS - показывает статус блока, точнее, в каком режиме он находится: Enter_Query (ввода запроса), Insert (вставки), New (новой записи).

SYSTEM.CURRENT_BLOCK - возвращает имя текущего блока.

SYSTEM.CURRENT_DATETIME - возвращает системную дату.

SYSTEM.CURRENT_ITEM - возвращает имя (если это кнопка, то также возвращает имя, а не метку ) текущего элемента блока.

SYSTEM.CURRENT_FORM - возвращает имя текущей формы.

SYSTEM.CURRENT_VALUE - возвращает текущее значение поля.

SYSTEM.CURSOR_BLOCK - возвращает имя курсора блока.

SYSTEM.CURSOR_ITEM - возвращает курсор на текущий элемент блока в формате block_name.item_name.

SYSTEM.CURSOR_RECORD - возвращает последовательный номер курсора записи.

SYSTEM.FORM_STATUS - ' CHANGED ', ' NEW ', ' QUERY '.

SYSTEM.LAST_QUERY - возвращает последний запрос.

SYSTEM.LAST_RECORD - возвращает TRUE, если достигнута последняя запись, и ' FALSE ', если наоборот.

SYSTEM.MESSAGE_LEVEL - эта одна из немногих системных переменных, которая не только возвращает значение, но и принимает его, позволяя разработчику контролировать уровень строгости сообщения. Чем больше уровень строгости, тем меньше системных сообщений

на экране. Если в процессе работы формы требуется вывести сообщение, то оно будет выведено только в том случае, когда уровень этого сообщения больше, чем значение SYSTEM.MESSAGE_LEVEL. В противном случае сообщение будет проигнорировано.

По умолчанию значение SYSTEM.MESSAGE_LEVEL равно 0, и это значит, что Oracle Forms будет выводить любые сообщения. Исходя из списка возможных уровней, мы знаем 6 значений, которые имеет смысл присваивать переменной SYSTEM.MESSAGE_LEVEL: 0, 5, 10, 15, 20, 25. Каждый вышестоящий уровень подавляет нижестоящий. Присвоение переменной SYSTEM.MESSAGE_LEVEL значения 10 будет означать, что все сообщения, имеющие уровень 5 или 10, больше выводиться не будут.

SYSTEM.MODE - возвращает текущий режим форма запроса.

SYSTEM.MOUSE_BUTTON_PRESSED - возвращает значение состояния кнопки. Состояние TRUE означает, что кнопка мыши нажата. SYSTEM.MOUSE_BUTTON_SHIFT_STATE - возвращает состояние курсора на кнопке.

SYSTEM.MOUSE_X_POS - возвращает значение позиции курсора мыши на экране по X.

SYSTEM.MOUSE_Y_POS - возвращает значение позиции курсора мыши на экране по Y.

SYSTEM.RECORD_STATUS - эта переменная показывает, в каком режиме находится запись: CHANGED, INSERT, NEW, QUERY.

SYSTEM.SUPPRESS_WORKING - подавляет стандартные рабочие сообщения, если SYSTEM.SUPPRESS_WORKING:= TRUE.

SYSTEM.TRIGGER_BLOCK - возвращает курсор блока, когда текущий триггер инициализирован.

SYSTEM.TRIGGER_ITEM - возвращает курсор элемента блока, когда текущий триггер инициализирован.

SYSTEM.TRIGGER_RECORD - возвращает последовательный номер записи.

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

  1. :SYSTEM.CURSOR_BLOCK
    Declare
    Curr_bl varchar2(90):= :system.current_block
    If :system.current_block='Zak' then
     Set_block_property(curr_bl, update_allowed, property_false);
     Set_block_property(curr_bl, delete_allowed, property_false);
     Set_block_property(curr_bl, insert_allowed, property_false);
     …
    End if;
    End;

    В этом примере системная переменная используется для проверки имени блока, и в случае совпадения имени со значением условия выполняется некоторое действие, а именно запрет на операции DML в блоке.

  2. :SYSTEM.CURSOR_RECORD

    Вы можете использовать эту переменную для генерирования последовательности записей. Например, у вас в блоке одновременно отображается десять записей и вам нужно пронумеровать каждую новую запись. Для этого можно создать триггер WHEN-NEW-ITEM-INSTANCE на уровне блока и в теле триггера написать:

    :zak.num:=:SYSTEM.CURSOR_RECORD

    Если вы выполните этот пример, то увидите, как при переходе на следующую запись элемент :num принимает значение последовательного номера записи. Можно записать пример намного проще:

    Message('Номер записи: ':SYSTEM.CURSOR_RECORD);
  3. :SYSTEM.DATE_THRESHOLD :System.Date_Threshold := '01:00' ;
  4. :SYSTEM.EFFECTIVE_DATE :System.Effective_Date := '01-Декабрь-2007 11:00:00' ;
  5. :SYSTEM.MOUSE_BUTTON_PRESSED
    Declare
     Btn_press Varchar2(21) := :System.Mouse_Button_Pressed ; Begin
     If Btn_press = '1' Then
      Message('Нажата левая кнопка' );
     ElsIf Btn_press = '2' Then
      Message('Нажата правая кнопка' ); 
     Else
      Message('Другая клавиша' ); 
     End if ; 
    End ;

    В этом примере показано, как с помощью системной переменной проверяется нажатие клавиши.

  6. :SYSTEM.LAST_RECORD
    Begin
     First_Record ; 
     Loop
        Exit When :System.last_Record = 'TRUE' ; 
      :num:=: system.cursor_record;
      Message('Это была запись №_ '||:system.cursor_record)
      Next_Record ; 
     End loop ; 
    End ;

    В этом примере системная переменная :system.last_record используется для проверки условия выхода из цикла, так как возвращает значение ' TRUE ', если текущая запись последняя.

  7. :SYSTEM.MESSAGE_LEVEL Уровни строгости сообщения:
    • 0;
    • 5;
    • 10;
    • 15;
    • 20;
    • 25.
    Declare
     Mess_lev Pls_Integer := :System.Message_Level ; 
    Begin 
     Insert into Zak values(...)
     :System.Message_Level := 5 ;
     Commit_Form ;
     :System.Message_Level := Mess_lev; 
    End ;

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

  8. :SYSTEM.FORM_STATUS
    • CHANGED ;
    • NEW ;
    • QUERY.
    If :SYSTEM.FORM_STATUS = 'CHANGED' Then
     Message('Форма находится в режиме:'||:SYSTEM.FORM_STATUS);
     …; 
    End if;

    В этом примере проверяется статус формы и выводится на экран в виде сообщения.

  9. :SYSTEM.BLOCK_STATUS
    • CHANGED ;
    • NEW ;
    • QUERY.
    If :SYSTEM.BLOCK_STATUS = 'Query' Then
     Go_item(:num); 
     LIST_VALUES; 
    End if ;

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

  10. :SYSTEM.RECORD_STATUS
    • CHANGED ;
    • INSERT ;
    • NEW ;
    • QUERY.
    If :SYSTEM.RECORD_STATUS in ('CHANGED') then
     Commit_form;
     Go_block('pzak');
     Execute_query;
    End if;

    В этом примере проверяется статус блока, и если он находится в режиме изменения, то выполняется сохранение и запрос данных.

  11. :SYSTEM.CURRENT_VALUE
    If :system.current_value>100 then
     …
    End if;

    В этом примере идет проверка значения элемента, и если оно больше заданного, то выполняется какое-либо действие.

  12. :SYSTEM.MASTER_BLOCK
    Copy(name_in(:System.Master_Block||'.primary_item'), 'detail_block.detail_item');

В этом примере системная переменная используется для определения имени Мастер блока. С помощью команды COPY значение первичного ключа Мастер блока ( primary_item ) копируется в элемент подчиненного блока ( detail_block.detail_item ).

< Лекция 1 || Лекция 2: 123 || Лекция 3 >
Константин Лукин
Константин Лукин

ошибка: FRM47337  Tree node label can not be null

при выполнении скрипта

DECLARE
 Itree ITEM;
 top_node Ftree.Node;
 new_node Ftree.Node;
 i_value VARCHAR2(30);
BEGIN
 Itree := Find_Item('tree_block.tree_item ');
 new_node := Ftree.Add_Tree_Node(Itree, Ftree.ROOT_NODE,
   Ftree.PARENT_OFFSET, Ftree.LAST_CHILD,
   Ftree.EXPANDED_NODE, i_value, NULL, i_value);
END;

Юлия Малыгина
Юлия Малыгина
приведена функция скрытия URL отчета и ее применение, но применения так и нет
Андрей Кошелев
Андрей Кошелев
Россия, Москва, Московская Финансово-Юридическая Академия
Артем Чуйко
Артем Чуйко
Россия, Самара