VARIABILE SI BLOCURI DE CONTROL
CONTINUTUL ACESTUI UNIT
In acest capitol,vom invata cum sa construim si sa populam un bloc de control
si cateva utilizari ale blocurilor de control.
Se vor trata urmatoarele aspecte:
- Variabile in SQL*FORMS
- Referinte la obiecte in PL/SQL
- Utilizarea blocurilor control
- Definirea unui bloc de control
- Trigger-ele Pre-Form si Key-Startup
VARIABILELE IN SQL*FORM
- Exista patru tipuri de variabile :
- Campuri ecran (Screen fields) - orice camp ecran cum ar fi : base table,
non-base table ,ascuns sau afisat.
- PL/SQL - sunt folosite pentru a pastra valori temporare pe timpul procesarii
unui bloc PL/SQL.
- Globale - cum sugereaza si numele lor,sunt globale unei sesiuni SQL*FORMS .
Ele sunt imediat identificate datorita prefixului: GLOBAL.Variabilele globale
sunt de obicei folosite pentru a pasa valori intre forms-uri si a face
disponibila informatia pentru toate trigger-ele aplicatiei.
Se creeaza variabile globale cand este nevoie de ele,folosindu-le ca
tinta intr-o atribuire sau intr-o instructiune select.
- Sistem (System) - sunt create de catre SQL*FORMS si,cu o singura exceptie
(SYSTEM.MESSAGE_LEVEL),sunt "read only".Sunt imediat identificate datorita
prefixului SYSTEM.Variabilele sistem pastreaza informatie referitoare la
starea curenta a form-ului si sunt folositoare pentru a face codul
trigger-ului mai flexibil (vezi UNIT 15).
- Scopul variabilelor
Tip variabila Scop
-variabila PL/SQL -blocul PL/SQL in care este declarata
-camp ecran -form-ul curent
-variabila sistem -form-ul/menu-ul curent
-variabila globala -sesiunea SQL*FORMS/SQL*MENU
curenta
- Declararea unei variabile
DECLARE record_count NUMBER;
BEGIN
SELECT count(*)
INTO record_count
FROM customer
WHERE state = :cus.state;
...
Doar variabilele PL/SQL trebuie sa fie declarate inainte de a fi referite.Daca
sunt folosite,ele trebuie declarate inaintea oricaror declaratii executabile.
In exemplul de mai sus,record_count este o variabila PL/SQL,iar cus.state este
un camp ecran.
Cand declaram o variabila PL/SQL de tip CHAR sau NUMBER,trebuie specificata
marimea,spre exemplu:
DECLARE name CHAR(25);
DECLARE today DATE;
VARIABILE GLOBALE
Variabilele globale sunt :
- de cel mult 255 caractere
- folosite la transmiterea de valori intre forms-uri
- intotdeauna de tipul CHAR
Patru moduri de a crea variabile globale:
- atribuirea unei valori
- folosirea lui Default_Value
- select...into
- procedura de tip copy packaged
Doua moduri de a sterge variabilele globale:
- folosirea procedurii de tip Erase packaged
- terminarea sesiunii Runform
Variabilele globale pot contine siruri de cel mult 255 caractere lungime.
:GLOBAL.counter := 0;
:GLOBAL.counter := TO_NUMBER ( :GLOBAL.counter ) + 1;
Sunt patru moduri de a crea variabile globale :
- atribuirea unei valori
- folosirea lui Default_Value
- select...into
- procedura de tip copy packaged
Doua moduri de a sterge variabilele globale:
- folosirea procedurii de tip Erase packaged
- terminarea sesiunii Runform
Niciodata nu trebuie referita o variabila globala intr-o expresie PL/SQL
(alta decat o tinta a unei instructiuni de atribuire) inainte sa se stie
ca exista.Forms-urile vor semnala acest lucru ca un "warning "
pentru utilizator:
FRM-40815: Variable GLOBAL.tadpole does not exist.
Procedura de tip Default _Value packaged este folositoare pentru a evita
aceasta eroare.Vezi UNIT 14.
REFERINTE LA OBIECTE IN PL/SQL
Cum sa adresezi valoarea(VALUE) unei variabile:cand adesezi valoarea unei
variabile SQL*FORMS (camp ecran,variabila globala sau sistem) se precede
numele variabilei cu ':'.
A nu se folosi ':' pentru a adresa o variabila
locala PL/SQL.
Exemple:
:SYSTEM.CURRENT_FORM
:block_x.field_y
:GLOBAL.any_variable
local_variable
Nota:
Daca acelasi nume de camp apartine la mai mult de un camp in form,
TREBUIE prefixat numele campului cu numele blocului.Este,in orice caz,
recomandat ca intotdeauna sa prefixezi numele campului cu numele blocului.
Cum sa adresezi numele (NAME) unui obiect:cand adresezi numele unui obiect
SQL*FORMS(camp ecran,variabila globala sau sistem,nume de bloc sau form)
se incadreaza numele obiectului intre apostroafe.Sa nu se foloseasca
apostroafe pentru a adresa variabile locale PL/SQL.
Exemple:
'formname'
'blockname'
'fieldname'
'SYSTEM.variablename'
local_variable
BLOCURI DE CONTROL
Ce este un bloc de control ?
Un bloc de control nu este asociat cu orice tabela din baza de date.De altfel
el contine numai campuri din non-base table.
Utilizari ale blocurilor de control.
Blocurile de control sunt folosite oricand se doreste afisarea unui grup de
informatie care nu vine direct din baza de date.Se pot folosi blocurile de
control pentru a afisa informatii operatorilor cum ar fi data si timpul curent
sau informatii statiatice.Ele pot fi folosite de asemenea pentru meniuri,
ecrane de help,header-e de informatie si zone de scratch.
Exemplu de Control Block Menu:
________
| ORDER |
/-->| ENTRY |
_____________________ / | FORM |
| MAIN MENU | / |________|
| | /
| 1.Order Entry |/
| 2.Product Maint| ___________
| 3.Reporting_ / | | PRODUCT |
| |_| |----------------->| MAINT. |
|__________________\ _| | FORM |
\ |___________|
\
\ ________
\ | REPORT |
\->|________|
|________|
|________|
|________|
Popularea unui bloc de control .
Campurile unui bloc de control pot fi populate prin intermediul unui
trigger,valori implicite si ,daca sunt introductibile,folosind input.
In fond,este posibil sa definiti un bloc de control fara cimpuri
introductibile.in acest caz,blocul va fi ignorat pentru scopuri de
navigare si eroare va apare daca procedura packaged(GO_BLOCK,
GO_FIELD) doreste sa mute cursorul la bloc.
DOUA NOI TIPURI DE TRIGGER-E
In scopul de a popula un bloc de control intr-o intrare a unui form,
utilizatorul poate defini unul din cele doua tipuri de trigger-e care sunt
amandoua definite la nivelul form-ului.
Trigger-ele Pre-Form
Un trigger Pre-Form este primul trigger al oricarui form ce este
executat.In fond,este executat INAINTE ca form-ul sa fie afisat.
Din aceasta cauza ,este de obicei folosit pentru a verifica
drepturile de acces ale utilizatorului la form.
Exemple:
PRE-FORM trigger on any form
---------------------------------------------------------
IF TO_CHAR(SYSDATE,'D') BETWEEN '2' AND '6' THEN
MESSAGE ('HAVE A NICE DAY');
ELSE
MESSAGE('SORRY,NO WORK ALLOWED ON WEEKENDS!');
RAISE FORM_TRIGGER_FAILURE;
END IF;
_________________________________________________________
Trigger-ele Key-Startup
KEY-STARTUP este executat dupa un trigger PRE-FORM odata ce form-ul
este afisat.Numele sau ciudat deriva mai degraba ca chiar si daca nu
corespunde unei apasari de taste,el se comporta conform unei function
key apasate de utilizator.De exemplu,utilizatorii folosesc frecvent
KEY-STARTUP sa execute un query automat asupra unei intrari a unui
help form.
Un caz tipic de trigger Key-Startup va arata astfel:
KEY-STARTUP
-------------------------------------
SELECT SYSDATE,USER
INTO :GLOBAL.TODAY,
:GLOBAL.CURR_USER
FROM SYS.DUAL;
:CTL.TODAY := :GLOBAL.TODAY;
:CTL.CURR_USER := :GLOBAL.CURR_USER;
EXECUTE_QUERY;
-------------------------------------
FOLOSIREA BLOCURILOR DE CONTROL PENTRU
HEADER-ELE STANDARDIZATE
PRE-FORM
-------------------------------------
SELECT SYSDATE,USER
INTO :GLOBAL.TODAY,
:GLOBAL.CURR_USER
FROM SYS.DUAL;
:CTL.TODAY := :GLOBAL.TODAY;
:CTL.CURR_USER := :GLOBAL.CURR_USER;
EXECUTE_QUERY;
-------------------------------------
-------------------------
| ____________ |
| Date: | 01-JAN-95 | |
| |___________| |
|________________________|
| |
| -------------------------
| | ____________ |
| | Date: | 01-JAN-95 | |
| | |___________| |
| |________________________|
| | |
| | -------------------------
| | | ------------ |
| Page 1 | | Date: | 01-JAN-95 | |
|________| | |___________| |
| |_______________________|
| | |
| | |
| | |
| | |
| Page 2| |
|________| |
| |
| |
| |
| Page 3 |
|_______________________|
!!! Atentie la folosirea variabilelor globale !!!
BLOCURILE POT UMPLE (SPAN) PAGINI
Blocurile nu sunt asociate cu anumite pagini(mai putin initial cand sunt
create prin intermediul facilitatii Default Block).Fiecare camp al blocului
trebuie sa fie plasat intr-o pagina.Creand sau mutand campuri ale blocului
in diferite pagini se forteaza blocul sa umple pagini.
Frecvent blocurile de control umplu pagini.De exemplu,intr-un form multi-
page un bloc de control poate fi folosit pentru a afisa un header standard
la inceputul fiecarei pagini.Pasii de mai jos sunt o sugestie de definire
a unui astfel de bloc de control.
FOLOSIREA BLOCURILOR DE CONTROL PENTRU
HEADER-E STANDARDIZATE
- Folosind tabela Block Definition a form-ului,se creeaza un nou bloc cu
un nume semnificativ cum ar fi CTL sau HEADER.
- Se apeleaza screen painter-ul si se verifica daca contextul blocului este
blocul de control si daca contextul paginii este prima dintre paginile
primita de header.
- Se creeaza campurile dorite.Daca aceleasi campuri vor fi definite si in
alte pagini adaugati numarul paginii la numele de baza al campului(de
exemplu TODAY1).Se asigura ca Base Table Attribute este neselectat pentru
fiecare.
- Se adauga orice imagine grafica se doreste.
- Asupra ariei blocului se executa Cut si Paste.
- Apasati [ Next Page ] si [ Paste ] continutul buffer-ului in pagina.
Se redenumeste fiecare camp,incrementand sufixul cu 1 (de exemplu: TODAY1
devine TODAY2).
- Repetati pasii 5 si 6 pana cand blocul de control umple toate paginile.
- Populati campurile blocului de control prin intermediul unui trigger
PRE-FORM sau KEY-STARTUP.
VARIABILE GLOBALE PENTRU INFORMATII
DE CONTROL
Avantajul folosirii variabilelor globale pentru pastrarea informatiilor
header este acela ca ele retin valorile lor cand form-ul este curatat.Ele
pot fi folosite pentru a reface campurile header salvand accese inutile la
baza de date.Variabilele globale sunt globale unei sesiuni SQL*FORMS si sunt
identificate cu ajutorul prefixului :GLOBAL.Pentru a crea o variabila
globala se atribuie (selecteaza) o valoare.
UNIT 11 -- EXERCITII :
Exercitiul A:Crearea unui bloc de control
In acest exercitiu,se va face un bloc de control ce va
afisa data si user_id al operatorului in pagina 1 si 2.
- Crearea unui bloc numit CTL cu non-base table si a unei
sequence number de 4.
- Activati screen painter-ul.Fiti sigur ca pagina dorita
este afisata si contextul blocului este CTL.
- Crearea urmatoarelor campuri:
Lengths
Name: Data Type: Field Display Page:
-------------------------------------------------
TODAY1 CHAR 40 40 1
USER1 CHAR 12 12 1
TODAY2 CHAR 40 40 2
USER2 CHAR 12 12 2
Parasiti Query Length.Deselectati toate Select Attributes
cu exceptia lui Displayed si Echo Input.
________________________________________________________________________
| |
| Date: Friday the 17th of July User: FM3T1 |
| |
| --ORDER-SUMMARY----------------------------------------------------- |
| |
| Ordid 601 Commplan A Orderdate 01/05/86 |
| Custid 106 Name SHAPE UP Shipdate 30/05/86 |
| Repid 7844 Name TURNER Total 2.40 |
| |
| --ITEM DETAILS------------------------------------------------------ |
| |
| Itemi Prodid Describ Stdprice Actualpri Qty Itemtot |
| 1 200376 SB ENERGY BAR-6 PACK 5 2.40 1 2.40 |
| |
| |
| Count: 3 Replace |
|______________________________________________________________________|
Exercitiul B:Popularea unui bloc de control
- Se scrie un trigger PRE-FORM pentru a copia data
curenta si used_id-ul operatorului in campurile
blocului de control.Asigurati-va de stergerea
contextului de bloc si camp al trigger-ului>br>
Sugestie pentru formatul datei:
FRMDay, "the" ddth "of" Month YYYY.
Initial se populeaza o pereche de variabile globale,
apoi se atribuie valorile acestora campurilor din
ecran.
- Se genereaza si testeaza acest form.
Daca mai aveti timp:
- Imbunatatiti trigger-ul PRE-FORM de la pasul 1
pentru a afisa un mesaj sugestiv si sa esueze daca
utilizatorul acceseaza form-ul in afara orelor normale
de lucru.Desigur,in scopul de a testa form-ul in
timpul orelor de lucru,va trebui sa setati timpul.
UNIT 11 -> SOLUTII :
Exercitiul A:Crearea unui bloc de control
-
----------------------------------------------------------------
| Block: CTL | -- Records -- | Array Size: |
| Table: | Displayed: 1 | [ ] Prim Key |
| Sequence Number: 4 | Buffered: | [ ] In Menu |
| | Lines per: | [ ] Column Sec |
|---------------------------------------------------------------|
| Description: |
|---------------------------------------------------------------|
|---------------------------------------------------------------|
|------------------Default Where/Order By-----------------------|
| |
| |
| |
| |
| |
|---------------------------------------------------------------|
|-------------------------Comment-------------------------------|
| |
| |
| |
| |
| |
|_______________________________________________________________|
Nici o solutie formala pentru pasii 2 si 3.
Exercitiul B:Popularea unui bloc de control
- Trigger PRE-FORM la nivelul Form
SELECT TO_CHAR(SYSDATE, 'FMDay, "the" ddth "of" FMMonth'), USER
INTO :GLOBAL.TODAY,
:GLOBAL.CURR_USER
FROM SYS.DUAL;
:CTL.TODAY1 := :GLOBAL.TODAY;
:CTL.TODAY2 := :GLOBAL.TODAY;
:CTL. USER1 := :GLOBAL.CURR_USER;
:CTL. USER2 := :GLOBAL.CURR_USER;
Nota:Daca acest trigger nu este la nivelul form nu va functiona.
- Nici o solutie formala.
- Adaugati urmatorul cod la sfarsitul zonei de text a trigger-ului din
pasul 1:
IF TO_CHAR(SYSDATE,'hh24ml') NOT BETWEEN '0900' AND '1730' THEN
MESSAGE ('sorry' ||:global.curr_user|| 'you cannot work outside
office hours!');
RAISE FORM_TRIGGER_FAILURE;
END IF;