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 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:

  1. Transfera controlul sistemului de operare
  2. SQL*PLUS este invocat
  3. SQL*PLUS culege parola din REP1.SQL
  4. Report-ul este rulat folosind continutul lui :DEPT.DEPTNO pentru &1 si :EMP.JOB pentru &2.
  5. 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



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:
         _________________________________________________________________
        |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...



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