PROCEDURI PACKAGED NELIMITATE
Scopurile acestei lucrari
Aveti deja o experienta de lucru asupra catorva proceduri packaged
(de impachetare) limitate.
Aceasta lucrare va prezinta o gramada de proceduri packaged nelimi-
tate si da exemple la cateva.
Subiectele principale sunt:
- proceduri nelimitate
- exemple folosind proceduri packaged
- erori capcana
Proceduri packaged nelimitate
Orice procedura packaged care nu impiedica functiile de baza ale
SQL*Forms este o procedura packaged NELIMITATA si este apelabila din orice
tip de trigger.
Urmatoarele proceduri packaged pot fi apelate din orice tip de trigger:
ABORT_QUERY 3 HIDE_MENU
3 ANCHOR_VIEW+ 3 HIDE_PAGE+
BELL HOST+
3 BREAK 3 LOCK_RECORD
* CALL+ MESSAGE+
* CALL_QUERY+ 3 MOVE_VIEW+
COPY+ PAUSE
DEFAULT_VALUE+ PRINT
DISPLAY_ERROR REDISPLAY
3 DISPLAY_FIELD+ 3 REPLACE_MENU+
3 DISPLAY_PAGE+ 3 RESIZE_VIEW+
ERASE+ 3 SET_FIELD+
EXECUTE_TRIGGER+ 3 SET_INPUT_FOCUS+
(daca trigger-ul numit 3 SHOW_MENU
de utilizator utilizeaza 3 SHOW_PAGE+
numai proceduri packaged * SYNCHRONIZE
nelimitate) 3 USER_EXIT+
--------------------------------------------------------------------------
| Cheia: |
| |
| + necesita argument(e) (+) argument(e) optional(e) |
| * echivalent cu V2 dar cu 3 neobisnuit cu V3 |
| functionalitate multipla |
---------------------------------------------------------------------------
Cand referiti orice procedura packaged intr-un trigger, limitata sau
nelimitata, trebuie intotdeauna sa luati in considerare daca tipul trigger-
ului este corespunzator si daca imprejurarile in care trigger-ul va fi lansat
sunt valide pentru functiile pe care doriti ca triggr-ul sa le execute.
O procedura pe care deja o cunoasteti:
- MESSAGE
- Sintaxa:MESSAGE(message_string);
Puteti afisa un mesaj de pana la 78 caractere
pe ecran.
Pentru a afisa un apostrof, utilizati doua.
Exemple: MESSAGE('Don''t have a nice day!');
MESSAGE('Department'|| to char
(:dept.deptno)||' does not exist.');
Proceduri nelimitate care executa functii Key-Like
Aceste proceduri packaged sunt nelimitate, chiar daca totusi executa
actiuni asociate direct sau indirect cu cheile functilor.
- ABORT_QUERY
- Sintaxa:ABORT_QUERY;
ABORT_QUERY inchide o intrebare ce este deschisa in
blocul curent.
- BELL
- Sintaxa:BELL;
BELL semnalul sonor al terminalului la urmatorul
moment cand ecranul terminalului este sincronizat cu
starea interna a structurilor.
- DISPLAY_ERROR
- Sintaxa:DISPLAY_ERROR
DISPLAY_ERROR afiseaza ecranul Display Error(Erori de
afisare) daca s-a produs o eroare logica.
- LOCK_RECORD
- Sintaxa:LOCK_RECORD;
Incearca sa inchida in baza de date acel sir care co-
respunde inregistrarii curente. Vezi trigger-ul ON_LOCK
in lectia 19.
- PAUSE
- Sintaxa:PAUSE
PAUSE suspenda procesarea pana ce operatorul apasa o
cheie functionala.PAUSE poate afisa o alarma.
- PRINT
- Sintaxa:PRINT
PRINT afiseaza fereastra Print Screen. Atunci utiliza-
torul poate sa ceara scrierea paginii curente a unei
structuri intr-un fisier.
- REDISPLAY
- Sintaxa:REDISPLAY;
REDISPLAY redeseneaza ecranul.
- SYNCHRONIZE
- Sintaxa:SYNCHRONIZE;
SYNCHRONIZE face update ca afisajul ecranului sa reflecte
informatiile pe care SQL*Forms le are in reprezentarea
sa interna
Exemplul 1:
Urmatorul trigger renunta la o intrebare dupa afisarea celor 10 inre-
gistrari.
Post-Query
------------------------------------------------
IF :System.Trigger_Record > 10 THEN
MESSAGE('10 records displayed; query aborted');
END IF;
-------------------------------------------------
Exemplul 2:
In trigger-ul de mai jos, daca utilizatorul raspunde 'YES', casuta
de dialog Print se va afisa automat.
ON-VALIDATE-FIELD on Print_It Field
---------------------------------------------
IF :menu.print_it = 'YES' THEN
PRINT;
END IF;
---------------------------------------------
Exemplul 3:
Codul de mai jos va activa semnalul sonor al terminalului cat timp
se afiseaza un mesaj catre operator.
IF :menu.choise NOT IN ('1','2','3') THEN
BELL;
MESSAGE(Please choise 1, 2 or 3');
END IF;
Exemplul 4:
Procedura package SYNCHRONIZE este folosita in exemplul de mai jos
pentru a forta SQL*Forms sa "picteze" fiecare pagina pe ecran intr-o
actiune separata.
SHOW_PAGE(1);
SYNCHRONIZE;
SHOW_PAGE(2);
SYNCHRONIZE;
SHOW_PAGE(3);
SYNCHRONIZE;
Proceduri care renunta la forma curenta
- HOST
- Sintaxa:
HOST(system_command_string[,NO_SCREEN]);
HOST executa o comanda indicata a sistemului de operare.
Daca folositi parametrul NO_SCREEN SQL*Forms nu sterge ecranul
si nu obliga operatorul sa se intoarca din comanda.
Nota: HOST trebuie sa fie dat intotdeauna cu o comanda valida
spre executie. Nu poate fi utilizat simplu pentru a iesi din
sistemul de operare.
- CALL
- Sintaxa: CALL(form_name[,{HIDE|NO_HIDE}
[,{DO_REPLACE|NO_REPLACE}]]);
CALL executa structura indicata, dar pastreaza structura ape-
lanta activa. Cand utilizatorul face o iesire normala din
structura apelata, controlul este redat structurii apelante.
HIDE determina SQL*Forms sa stearga structura apelanta de pe
ecran inainte de a desena structura apelata; NO_HIDE permite
structurii apelante afisarea in background.
NO_REPLACE determina SQL*Forms sa foloseasca meniul default
(de lipsuri) al structurii apelate; DO_REPLACE indica faptul
ca meniul default al structurii apelate ar trebui utilizat.
Cand o structura este apelata, SQL*Forms publica un punct de
salvare. Functia CLEAR_FORM in structura apelata va rerula
schimbarile neefectuate la acest punct de salvare.
- CALL_QUERY
- Sintaxa: vezi CALL.
CALL_QUERY ruleaza structura apelata doar in modul intrebare,
adica utilizatorii (si trigger-ele) nu pot utiliza inserari,
stergeri.
- USER_EXIT
- Sintaxa: USER_EXIT(user_exit_string[,error_string]);
unde:
- user_exit_string specifica numele utilizatorului iesit pe care
vreti sa-l apelati si cativa parametri.
- error_string contine un mesaj de eroare pe care SQL*Forms il
face accesibil daca iesirea utilizatorului nu a reusit.
USER_EXIT apeleaza utilizatorul iesit numit de user_exit_string.
Exemplul 1:
Acest trigger invoca SQLPLUS cu un OPS$ si parola. Report-ul
numit REP1.SQL va fi executat. -S ruleaza SQL*Plus in mod
"linistit".
-------------------------------------------------
HOST('SQLPLUS -S / @REP1");
-------------------------------------------------
Exemplul 2:
Presupunem ca aveti un fisier SQL*PLUS care arata asa:
REP1.SQL
----------------------------------------------
irving/washington
SELECT * FROM EMP
WHERE DEPTNO = &1 AND JOB = '&2'
/
EXIT
-----------------------------------------------
Trigger-ul pentru a executa report-ul din SQL*Forms arata cam
asa:
-----------------------------------------------
HOST('SQLPLUS -S @REP1 '||To_Char(:DEPT.DEPTNO)||' '||:EMP.JOB);
-----------------------------------------------
Urmatoarele actiuni au loc:
- Transfera controlul sistemului de operare
- SQL*PLUS este invocat
- SQL*PLUS culege parola din REP1.SQL
- Report-ul este rulat folosind continutul lui :DEPT.DEPTNO
pentru &1 si :EMP.JOB pentru &2.
- Cand este intalnita comanda EXIT, controlul se transfera
inapoi structurii apelante.
Exemplul 3:
Aceasta bucata de cod de trigger apeleaza o strustura help.
Daca structura help este o pagina pop-up, o parte din struc-
tura apelanta poate ramane afisata.
---------------------------------------------------
CALL_QUERY('help_me', NO_HIDE);
---------------------------------------------------
Manipularea variabilelor si a campurilor ecranului
- COPY
- Sintaxa: COPY(value_string,field_name);
COPY scrie o valoare intr-un camp. In cele mai multe cazuri
utilizati operatorul de atribuire(:=) pentru a schimba valoarea
unui camp al ecranului sau a variabilei. COPY este folosit cand
cand un camp al ecranului sau o variabila este referita indirect.
Ca exemplu consideram ca in campul A avem numele campului B.
Vreti sa copiati o valoare in campul B. Nu puteti face acest
lucru utilizand un operator de atribuire.
Vezi lectia 15 si functia package pentru mai multe informatii.
- DEFAULT_VALUE
- Sintaxa: DEFAULT_VALUE(Value_string, variable_name);
DEFAULT_VALUE initializeaza(creeaza si atribuie o valoare la)
o variabila globala NUMAI DACA variabila nu exista deja.
Procedura package DEFAULT_VALUE este utila pentru a evita
eroarea:
FRM-40815:Variable GLOBAL.thingy does not exist.
- ERASE
- Sintaxa: ERASE(global_variable_name);
ERASE elimina variabila globala indicata astfel incat sa nu mai
existe si elibereaza memoria asociata cu variabila globala.
- BREAK
- Sintaxa: BREAK;
Daca structura curenta rulata in modul debug, BREAK opreste exe-
cutia structurii si afiseaza meniul Debug Mode Options. Daca
structura curenta nu este executata in modul debug, BREAK nu
face nimic. Utilizati BREAK pentru a vedea continutul varia-
bilelor GLOBAL, SYSTEM si page 0.
Exemplul 1:
Sirul de caractere 'PROVIDENCE' este copiat intr-o variabila
globala.
----------------------------------------
COPY('PROVIDENCE', 'GLOBAL.loc');
----------------------------------------
Exemplul 2:
O variabila globala este utilizata ca un flag. Prima data cand
se executa trigger-ul, GLOBAL.FIRST_TIME nu exista.
DEFAULT_VALUE il creeaza si il initializeaza.
DEFAULT_VALUE('Y' , 'GLOBAL.FIRST_TIME');
IF :GLOBAL.FIRST_TIME = 'Y' THEN
...
END IF;
:GLOBAL.FIRST_TIME := 'N';
Exemplul 3:
Cand o structura este rulata in modul debug, executarea proce-
durii package BREAK duce la afisarea meniului Debug Mode
Options. Meniul va da posibilitatea alegerii unor actiuni ca:
aratarea continutului variabilelor GLOBAL, SYSTEM sau page 0.
Desi nu este o procedura limitata, veti gasi BREAK cel mai mult
accesibil cand ati codat o cheie pe un trigger
KEY-NXTKEY
------------------
BREAK;
------------------
Proceduri package pentru pop_up-uri
Anchor_View
_________________________
| ______ ...... |
| | |----> . . |
| | | . . |
| | | . . |
| ------ ...... |
| |
| |
------------------------
Move_View
----------------------- _________________________
| _________ | | ____________ |
| | PIGS | |------> | | DON'T | |
| | FLY | | | | | |
| ------- | | ----------- |
----------------------- ------------------------
Resize_View
0____________........
| . | .
| . | .
|........ | .
| \| .
.------------\ .
. .
.....................
Controlul dinamic al ferestrelor Pop-Up si al meniurilor
Pentru paginile pop-up:
- ANCHOR_VIEW
- Sintaxa:
ANCHOR_VIEW(page_number,x_coordinate,y_coordinate);
ANCHOR_VIEW muta imaginea unei pagini la o noua
destinatie pe ecran.
- MOVE_VIEW
- Sintaxa: MOVE_VIEW(page_number,x_coordinate,y_coordinate);
MOVE_VIEW muta o imagine a unei pagini la o noua
destinatie in acea pagina. Aceasta procedura efectiv
schimba acea parte a paginii pe care operatorul o vede
in imagine. Aceasta nu schimba pozitia imaginii pe
ecran.
- RESIZE_VIEW
- Sintaxa: RESIZE_VIEW(page_number,width,height);
RESIZE_VIEW schimba dimensiunea imaginii paginii.
- HIDE_PAGE
- Sintaxa: HIDE_PAGE(page_number);
HIDE_PAGE face ca pagina indicata sa dispara din ecran.
HIDE_PAGE este ignorat daca pagina indicata este pagina
activa curenta.
- SHOW_PAGE
- Sintaxa: SHOW_PAGE(page_number);
SHOW_PAGE afiseaza pe ecran o pagina specificata.
Aceasta nu face ca pagina specificata sa devina activa.
SHOW_PAGE este ignorat daca pagina specificata ar aco-
peri pagina curenta.
- DISPLAY_PAGE
- Sintaxa: DISPLAY_PAGE(page_number,display_attribute);
DISPLAY_PAGE modifica felul in care o pagina apare pe
terminal prin stabilirea unui atribut de producere al
afisarii paginii. Numele atributelor disponibile sunt
stocate in Oracle*Terminal.
Urmatorul exemplu de trigger utilizeaza procedura RESIZE_VIEW pentru a schimba
dimensiunea paginii pop-up care este deja afisata pe ecran.
KEY-PRVFLD
-------------------------------------------------------------------------
DEFAULT_VALUE('0','GLOBAL.psize');
:GLOBAL.psize := TO_NUMBER( :GLOBAL.psize) + 1;
IF :GLOBAL.psize =1 THEN RESIZE_VIEW(2,35,5);
ELSIF :GLOBAL.psize = 2 THEN RESIZE_VIEW(2,50,10);
ELSIF :GLOBAL.psize = 3 THEN RESIZE_VIEW(2,65,15);
ELSIF :GLOBAL.psize = 4 THEN RESIZE_VIEW(2,80,20);
:GLOBAL.psize := 0;
END IF;
-------------------------------------------------------------------------
Schimbarea atributelor campului DISPLAY_FIELD
Schimbarea atributelor campului si caracteristicilor de afisare
- DISPLAY_FIELD
- Sintaxa:DISPLAY_FIELD(field_name,display_attribute_name);
DISPLAY_FIELD modifica acea cale prin care campul apare
pe terminal prin atribuirea unui atribut de afisare
specificat campului. Numele atributelor de afisare
disponibile sunt depozitate in Oracle*Terminal mapate
cu fiecare structura rulata.
Puteti referi orice camp in structura curenta. Nu
uitati ca DISPLAY_FIELD afecteaza doar afisarea cere-
rilor actuale ale campului; alte cereri ale campului
specificat nu sunt afectate. Aceasta inseamna ca daca
specificati o modificare a afisajului pentru un camp
care exista intr-un bloc multi-record, DISPLAY_FIELD
modifica doar cererea acelui camp care apartine record-
ului curent al blocului.
Orice modificare facuta de procedura package DISPLAY_
FIELD este valabila efectiv pana cand un alt DISPLAY_
FIELD care refera acelasi camp al structurii curente
este terminat.
Exemplu:
Trigger-ul testeaza continutul lui EMP.JOB. Daca acesta este
PRESIDENT campul este afisat ca bold. Daca job-ul este MANAGER,
job-ul este underline. Job-ul care nu e nici PRESIDENT nici
MANAGER este afisat ca si celelalte campuri ale structurii.
Key-Nxtfld on EMP.JOB
----------------------------------------------------
IF :EMP.JOB = 'PRESIDENT' THEN
DISPLAY_FIELD ('EMP.JOB','BOLD');
ELSIF :EMP.JOB = 'MANAGER' THEN
DISPLAY_FIELD ('EMP.JOB','UNDERLINE');
ELSE
DISPLAY_FIELD ('EMP.JOB','NORMAL');
END IF;
NEXT_FIELD;
-----------------------------------------------------
Schimbarea atributelor campului:SET_FIELD
- Afectarea tuturor cererilor campului
- Parametri
- AUTO_HELP
- AUTO_SKIP
- FIXED_LENGTH
- ENTERABLE
- REQUIRED
- ECHO
- QUERYABLE
- UPDATEABLE
- UPDATE_NULL
- UPPER_CASE
Schimbarea atributelor campului si a caracteristicilor de afisare
- SET_FIELD
- Sintaxa: SET_FIELD(field_name,
{AUTO_HEKP|AUTO_SKIP|FIXED_LENGTH|
ENTERABLE|REQUIRED|ECHO|QUERYABLE|
UPDATEABLE|UPDATE_NULL|
UPPER_CASE}[,ATTR_ON|ATTR_OFF}]);
SET_FIELD modifica un camp prin schimbarea unei
caracteristici specificate a campului. Puteti sa
schimbati doar o singura caracteristica a campului
la un moment dat. Caracteristicile sunt mapate la
urmatorii parametri:
Parametru Caracteristici
AUTO_HELP Help automat
AUTO_SKIP Skip automat
FIXED_LENGTH Lungime fixa
ENTERABLE Input permis
REQUIRED Cerut
ECHO Input cu ecou
QUERYABLE Intrebari permise
UPDATEABLE Update permis
UPDATE_NULL Update daca Null
UPPER_CASE Uppercase
Implicit SET_FIELD utilizeaza parametrul ATTR_ON.
Acest parametru determina SQL*Forms sa seteze caracteristicile
specificate "on". Daca folositi parametrul ATTR_OFF, SQL*Forms
seteaza caracteristicile specificate "off".
Orice modificari facute de procedura package SET_FIELD sunt valabile
pana cand un alt SET_FIELD modifica aceleasi caracteristici sau pana
cand structura curenta este "parasita".
Exemplu:
Acest trigger impiedica utilizatorul sa faca update pe
salariul cuiva.
PRE-RECORD
---------------------------------------------------
IF :EMP.ENAME = USER THEN
SET_FIELD('EMP.SAL',UPDATEABLE,ATTR_OFF);
MESSAGE('Salary on this record non-updateable');
ELSE
SET_FIELD('EMP.SAL',UPDATEABLE);
END IF;
----------------------------------------------------
Triggere numite de utilizator: EXECUTE_TRIGGER
Calc_Rem on EMP Block
________________________
| |
--------------->| |< ----------------------
| | | |
| _______________________ |
| |
| O-V-F on EMP.SAL O-V-F on EMP.COMM |
| ---------------- ---------------- |
| |EXECUTE_TRIGGER| |EXECUTE_TRIGGER| |
|_______|('calc_rem'); | |('calc_rem'); |_______|
| | | |
--------------- ----------------
Exemplu:
ON-VALIDATE-FIELD on both EMP.SAL and EMP.COMM
-----------------------------------------------
EXECUTE_TRIGGER('calc_rem');
-----------------------------------------------
CALC_REM on the EMP Block
-----------------------------------------------
:SCR_REM := :EMP.SAL *12 + NVL(:EMP.COMM,0);
-----------------------------------------------
Un trigger numit de utilizator, asa cum v-ati asteptat, este un trigger
care este numit de "proiectantul" structurii. Un trigger numit de utili-
zator se va executa doar cand un alt trigger il apeleaza prin procedura
package EXECUTE_TRIGGER.
- EXECUTE_TRIGGER
- Sintaxa: EXECUTE_TRIGGER(trigger_name)
Trigger-ele numite de utilizator au cateva avantaje:
- Salveaza codul repetitiv
- Reduc dimensiunea structurii
- Moduleaza codul dumneavoastra de trigger
- Ofera o intretinere mai usoara
_________________________________________________________________
|Lectia 15 acopera procedurile form-level care sunt mai flexibile|
| si mai eficiente pentru trigger-ele numite de utilizator |
-----------------------------------------------------------------
Scopul trigger-ului
Un trigger numit de utilizator poate fi accesibil pentru
fiecare trigger care il apeleaza. Din acest motiv trigger-ele
numite de utilizator sunt de obicei definite in bloc sau struc-
tura level. Daca CALC_REM va fi vreodata apelat doar din campuri
in blocul EMP, aceasta este aproape de definirea sa ca bloc
level trigger.
Cand o procedura package esueaza...
- Trigger-ul continua sa se execute
KEY-DOWN
-----------------
DOWN; --DOWN poate esua
NEXT_BLOCK; dar trigger-ul merge in continuare
DOWN;
PREVIOUS_BLOCK;
- Folosirea FORM_SUCCES pentru testare rezultat
KEY-DOWN
---------------------
DOWN;
IF FORM_SUCCES THEN
NEXT_BLOCK; --Face asta doar daca urmeaza DOWN
DOWN;
PREVIOUS_BLOCK;
END IF:
- CHECK_PACKAGE_FAILURE
O procedura package se spune ca a esuat daca nu-si poate indeplini
functionarea standard. De exemplu, CLEAR_BLOCK este emis, dar
comiterea esueaza datorita unei erori de validare. Blocul nu este
sters;din acest motiv procedura package a esuat.
Exemplu:
Doua blocuri contin inregistrari corelate. Inregistrarea 1 in blocul 1
corelata cu inregistrarea 1 in blocul 2, etc. Cand operatorul apasa
[DOWN] din blocul 1, urmatorul trigger porneste:
KEY-DOWN
-------------
DOWN; Trigge-ul On-Validate-Field esueaza,
NEXT_BLOCK; DOWN atunci esueaza, dar trigger-ul
DOWN; continua. Acum cele doua blocuri nu
PREVIOUS_BLOCK; mai sunt corelate.
Pentru a opri actiunea trigger-ului in cazul in care DOWN esueaza,
puteti testa rezultatul utilizand o functie package:
DOWN;
IF NOT FORM_SUCCES THEN
RAISE FROM_TRIGGER_FAILURE;
END IF;
NEXT_BLOCK; Faceti asta doar daca DOWN
DOWN; reuseste.
PREVIOUS_BLOCK;
FORM_SUCCES va fi TRUE daca reuseste DOWN. De aceea NOT FORM_SUCCES
este TRUE doar daca DOWN esueaza.
O solutie alternativa este prezentata pe pagina opusa.
Nota: procedura CHECK_PACKAGE_FAILURE generata de SQL*Forms indepli-
neste testul IF NOT FORM_SUCCES si esueaza pe TRUE. Daca structura
voastra contine deja aceasta procedura, utilizati-o pentru salvarea
propriei secvente de instructiuni codificate.
Folosirea functiilor package pentru capcanele ce produc esecul
- Testarea pentru reusita sau esec
- FORM_FAILURE
- FORM_SUCCES
- FORM_FATAL
- Testarea pentru erori specifice
- ERROR_CODE
- ERROR_NEXT
- ERROR_TYPE
Testarea pentru reusita sau esec
Urmatoarele functii package pot fi utilizate pentru testarea reusitei
sau esecului celei mai recente actiuni completate de SQL*Forms:
Numele functiei Returneaza TRUE daca Altfel returneaza
--------------- -------------------- ------------------
FORM_FAILURE rezultatul a fost esuat FALSE
FORM_FATAL rezultatul a fost eroare fatala FALSE
FORM_SUCCES rezultat reusit FALSE
Functiile FORM sunt reinitializate de fiecare cand actiunea SQL*Forms
e indeplinita. De aceea, testul poate veni imediat dupa ce actiunea este
executata, INAINTE ca orice actiune sa poata avea loc.
Testarea pentru erori specifice
La testarea pentru erorile specifice se folosesc urmatoarele functii
package:
Numele functiei Daca eroarea Daca eroarea nu
--------------- revine intamplator revine
------------------ ----------------
ERROR_CODE error code 0
ERROR_TEXT error text null
ERROR_TYPE FRM sau MNU sau ORA NULL
depinde de eroare
Exemplu:
Presupuneti ca doriti sa cititi o valoare lipsa intr-un camp
ORDERDATE numai daca procedura campului duplicat esueaza in timpul unui
trigger cheie deoarece nu a fost inregistrata in prealabil sa copieze
o structura a campului de valori. Din moment ce aceasta procedura poate
esua din mai multe motive, trebuie sa testati pentru o eroare
specifica:
KEY-DUPFLD
-----------------------------------------------------------------
DUPLICATE_FIELD;
IF ERROR_CODE = 41803 --Nu e nici o inregistrare pentru a copia
THEN valoarea de la
:ORD.ORDERDATE := SYSDATE;
END IF;
--------------------------------------------------------------------
CAPITOLUL 14 Exercitii
Proceduri package
- Scrieti un trigger pentru a apela structura TIMECHECK care este in
directorul vostru folosind CALL_QUERY. SQL*Forms sa nu curete direct
ecranul. Sugerati tipul trigger: Key-Nxtkey.
- Inserati procedura package BREAK in orice trigger doriti.
- Mutati in modul Debug, cand realizati si testati structura voastra.
- Creati o structura numita UTILITY care sa fie capabila sa execute
operarea sistemului de comenzi fara parasirea designer-ului
SQL*Forms.
Structura va fi alcatuita dintr-un bloc de control continand un
singur camp de intrare in care veti tipari comanda pe care doriti
sa o executati. Creati un trigger KEY-NXTFLD care va tipari o mul-
time de comenzi tinute in camp, afisand rezultatul pe ecran. Testati
structura voastra UTILITY prin afisarea continutului unui director.
(DIR command - VMS/DOS ls-Unix).
Exercitii suplimentare:
- Scimbati ON VALIDATE-FIELD pe campul QTY in blocul ITEM pentru a
face ca campul QTY sa fie underline cand o cantitate de 100 sau
mai mare este intrata. Un mesaj spunand 'Large order - please check
stock in hand.' ar putea fi afisat.
- Scrieti trigger-ul necesar pentru a permite operatorului sa mute
pagina pop-up"beneficiara" pe tot ecranul ori de cate ori el/ea
apasa [Block Menu].
Se face asa:
- a. Schimbati dimensiunea imaginii paginii voastre Cus pop-up
astfel incat sa fie mai mica decat jumatate din dimensiunea
ecranului.
- b. Redefiniti campul CUSTID in blocul CUS pentru a afisa urma-
torul mesaj ori de cate ori campul e introdus: 'Press Block
Menu to move this window'.
- c. Scrieti un trigger KEY-Menu in blocul CUS care muta pop-upul
la o noua pozitie pe ecran (stanga suu, dreapta jos, etc)
ori de cate ori utilizatorul apasa [Block Menu].
Sugestie: Formatul pentru ANCHOR_VIEW este aratat mai
jos:
ANCHOR_VIEW(page_number,x_coordinate,y_coordinate).
De exemplu ANCHOR_VIEW(2,40,1) ar trebui sa mute pagina pop-up
2 in cadranul din dreapta sus al ecranului.
CAPITOLUL 14 Solutii
1. KEY-NXTKEY at form level
-------------------------
CALL_QUERY('timecheck',no_hide);
------------------------
Nu sunt solutii formale pentru 2 si 3.
4. a
_____________________________________________________________
| |
| _____________UTILITY-FORM______________ |
| | Type O/S command at hit[Next Field]| |
| | | |
| | DIR*.INP | |
| ------------------------------------- |
| Count: *8 Replace |
-------------------------------------------------------------
b.
KEY-NXTFLD on CTL.CMD
-----------------------------------------------
HOST (:ctl.cmd);
-----------------------------------------------
5.
ON-VALIDATE-FIELD on ITEM.QTY
-------------------------------------------------------
:ITEM.ITEMTOT :=NVL(:ITEM.QTY*ITEM.ACTUALPRICE,0);
IF :ITEM.QTY >=100 THEN
DISPLAY_FIELD('ITEM.QTY','UNDERLINE');
MESSAGE('Large order - please check stock on hand');
ELSE
DISPLAY_FIELD('ITEM.QTY','NORMAL');
END IF;
-------------------------------------------------------
6. a
---------------------------------------------------------------
|Page| Pop-Up |Pg Sz|Pg Sz|Vw Sz|Vw Sz|Vw Lc|Vw Lc|Vw Pg|Vw Pg|
|Num | | X | Y | X | Y | X | Y | X | Y |
---------------------------------------------------------------
| 5 | [X] | 80 | 20 | 40 | 10 | 15 | 6 | 1 | 1 |
---------------------------------------------------------------
b.
Pentru CUS.CUSTID: Selectati Automatic Hint si schimbati mesajul Hint:
Hint: Apasati [Block Menu] pentru mutare pop-up.
c.
KEY-MENU on CUS block
---------------------------------------------------------------
default_value ('0','global.cpos');
:global.cpos :=to_number (:global.cpos)+1;
if :global.cpos = 1 then anchor_view(2,1,1);
elsif :global.cpos = 2 then anchor_view(2,40,1) ;
elsif :global.cpos = 3 then anchor_view(2,1,10);
elsif :global.cpos = 4 then anchor_view(2,40,10);
:global.cpos := 0;
end if;
---------------------------------------------------------------