Formele SQL au o multitudine de trasaturi ca, de exemplu, variabilele sis-
tem si functiile impachetate care dau mai multa flexibilitate codarii progra-
marii. Folosirea acestor proprietati permite scrierea de proceduri generice
care pot fi folosite sub orice forma intr-o aplicatie. Acest capitol contine
informatii despre:
SYSTEM.BLOCK_STATUS SYSTEM.CURRENT_FORM SYSTEM.CURSOR_BLOCK SYSTEM.CURSOR_FIELD SYSTEM.CURSOR_RECORD SYSTEM.CURSOR_VALUE SYSTEM.FORM_STATUS SYSTEM.LAST_QUERY SYSTEM.LAST_RECORD SYSTEM.RECORD_STATUS SYSTEM.TRIGGER_BLOCK SYSTEM.TRIGGER_FIELD SYSTEM.TRIGGER_RECORD
SYSTEM.MESSAGE_LEVEL SYSTEM.SUPPRESS_WORKING
Formele SQL pun la dispozitia programatorului mai multe variabile sistem
care ofera informatii despre forma sau obiectele SQL din forme in timpul se-
siunii RUNForm. In general, te poti referii la valoarea unei variabile sistem
pentru a controla felul in care se comporta o aplicatie.
Variabilele sistem sunt folositoare mai ales:
Formele SQL pastreaza valorile pe baza formelor. Adica valorile tuturor va-
riabilelor sistem corespund chiar formei curente.
O lista completa a numelor variabilelor sistem este in pagina urmatoare.
SYSTEM.MESSAGE_LEVEL si SYSTEM.SUPPRESS_WORKING sunt singurele variabile ale
caror valori pot fi schimbate. Valoarea lui STSTEM.MESSAGE_LEVEL determina ce
mesaje informationale, de avertizare sau eroare va trimite SQL*Forms operato-
rului.
SYSTEM.SUPPRESS_WORKING permite ca mesajul "in lucru" sa nu fie afisat.
CE CONTIN VARIBILELE SISTEM
Foloseste rularea pas cu pas pentru a te uita la variabilele sistem
____________________________________________________________________ | ______________________________________________ | | | | | | | Debug mode option | | | |______________________________________________| | | | Display Global Variables | | | | Display System Variables | | | | Display Page Zero Fields | | | | Continue with Debug Messages | | | | Continue without Debug Messages | | | | Exit Runform | | | |______________________________________________| | | | |____________________________________________________________________| Fig 16.1: Debug Mode Options Screen Numele si valoarea variabilelor sistem ______________________________________________________________________ | ___________________________________________________________________ | | | | | | | System Variable Name and Values | | | |------------------------------------------------------------------| | | || Trigger_Block | Item | | | || Trigger_Field | Item.Actualprice | | | || Current_Form | UNIT17 | | | || Current_Block | Item | | | || Trigger_Record | 2 | | | || Curent_Field | Actualprice | | | || Current_Value | 2.8 | | | || Cursor_Block | Item | | | || Cursor_Record | 2 | | | || Cursor_Field | Item.Actualprice | | | || Cursor_Value | 2.8 | | | || Message_Level | 0 | | | || Last_Query | Select ordid, itemid, prodid, actualp| | | || Record_Status | Query | | | || Last_Record | False | | | || Block_Status | Query | | | ||-----------------------------------------------------------------| | | | Please acknowledge screen Ok | | | |__________________________________________________________________| | | | |______________________________________________________________________| ______________________________________________________________________ | | | __________________________________________________________________ | | | | | | | | Form_Status | Query | | | | | Suppress_Working | False | | | |__________________________________________________________________| | | | |______________________________________________________________________| Fig 16.2: System Variables
Poate cel mai bun mod de a invata despre variabilele sistem este sa privesti
valorile lor cand o forma este in lucru. Procedura BREAK ne ofera aceasta po-
sibilitate atunci cand este executata in modul Debug.
Pentru a aparea fereastra Debug Mode Option ( vezi figura ) trebuie sa:
IF :SYSTEM.TRIGGER_RECORD = 'number'
IF :SYSTEM.LAST_RECORD = 'TRUE'
NUME VALOARE SEMNIFICATIE SYSTEM.RECORD_STATUS CHANGED Inregistrarea a fost adusa din baza de date si un camp BASE TABLE din in- registrare a fost actualizat. INSERT Utilizatorul(sau un trigger) a intro- dus o valoare intr-un camp BASE TABLE a unei inregistrari care nu a fost mai inainte chemata. NEW Inregistrarea nu exista inca, altfel spus, nici un camp BASE TABLE din in- registrare nu au fost completate de utilizator sau de trigger. QUERY Inregistrarea a fost adusa din baza de date dar nici un camp BASE TABLE din inregistrare n-a fost reactuali- zat. SYSTEM.FORM_STATUS CHANGED forma contine cel putin o inregistra- re in starea GHANGED sau INSERT. NEW forma contine numia inregistrari NEW. QUERY forma cotine numai inregistrari QUERY. SYSTEM.BLOCK_STATUS CHANGED blocul contine cel putin o inregistra- re in starea CHANGED sau INSERT. NEW blocul contine numai inregistrari NEW. QUERY blocul contine numai inregistrari QUERY.
KEY-CLRREC ------------------------------------------------------------------ IF :SYSTEM.RECORD_STATUS = 'CHANGED' OR :SYSTEM.RECORD_STATUS = 'INSERT' THEN COMMIT_FORM; END IF; CLEAR_RECORD; ------------------------------------------------------------------
KEY-EXEQRT ------------------------------------------------------------------ clear_dept_details; :system.suppress_working := 'TRUE'; execute_query; query_dept_details; :system.suppers_working := 'FALSE'; EXCEPTION when form_trigger_failure then null; ------------------------------------------------------------------
KEY-PRVFLD on ITEM.ITEMID ------------------------------------------------------------------ IF :SYSTEM.CURSOR_RECORD = '1' THEN GO_FIELD('ORD.TOTAL'); ELSE PREVIOUS_FIELD; END IF; ------------------------------------------------------------------
Fiecare mesaj al formelor SQL are asociat un nivel de severitate. Cele mai
putin severe mesaje ( ex: FRM-40100: La prima inregistrare ) sunt la nivelul 5,
in timp ce mesajele pentru cele mai grave erori ( ex: FRM-40024: Depaseste
memoria ) sunt la un nivel mai mare decit 25 si nu pot fi suprimate folosind
SYSTEM.MESSAGE_LEVEL.
Pe scurt, iata o descriere a nivelelor mesajelor de severitate:
NIVEL DE SEVERITATE DESCRIEREA MESAJULUI ------------------- -------------------- 0 ( toate tipurile de mesaje de la alte nivele de severitate ) 5 Reafirma o situatie evidenta. 10 Indica faptul ca operatorul a facut ceva inco- rect din punct de vedere procedural. 15 Declara ca operatorul incearca sa execute o functie pentru care nu exista forma. 20 Indica o stare in care operatorul nu mai poa- te continua o actiune pe care intentiona sa o termine din cauza unei probleme cu un trigger sau a unei alte situatii neobisnuite. 25 Indica o stare care poate face forma sa execu- te comanda incorect. mai mare de 25 Indica un grad de severitate al mesajului la care acesta nu mai poate fi suspendat prin intermediul variabilei SYSTEM.MESSAGE_LEVEL.Exemple:
KEY-ENTQRT on DEPT Block ------------------------------------------------------------------ :SYSTEM.MESSAGE_LEVEL := 5; ENTRE_QUERY; NEXT_BLOCK; EXECUTE_QUERY; IF NOT FORM_SUCCESS THEN MESSAGE('This departament has no employees'); END IF; PREVIOUS_BLOCK; :SYSTEM.MESSAGE_LEVEL := 0; ------------------------------------------------------------------
Se pot intercepta sau chiar suspenda de tot mesajele informative sau de
eroare ale formelor SQL.
Acestea permit intercepterea mesajelor de la formele SQL. Poti folosi functii
comprimate ( ex: ERROR_TEXT ) pentru a testa mesajele pe aceste triggere fiti
sigur ca utilizatorul primeste intotdeauna un mesaj al dvs. sau al formelor
SQL ori de cate ori un mesaj este asteptat.
In exemplul de mai jos trigger-ul afiseaza mesaje alcatuite pentru anumite
tipuri de erori dar, de asemenea pune la dispozitie formelor SQL un mesaj
standard implicit.
ON-ERROR on ORD.COMMPLAN ------------------------------------------------------------------ IF ERROR_CODE = 50001 OR ERROR_CODE = 40207 THEN -- alpha only/range check MESSAGE( 'You must enter A, B or C in this field'); ELSE MESSAGE( ERROR_TYPE||'-'||TO_CHAR(ERROR_CODE)||':'|| ERROR_TEXT); END IF; RAISE FORM_TRIGGER_FAILURE; ------------------------------------------------------------------ ________________________________________________________________________ | | | | | MAI MULTE PACHETE DE FUNCTII | | | | | | * PERMITE REFERINTA INDIRECTA | | | | NAME_IN | | | | * INTEROGHEAZA CARACTERISTICILE OBIECTULUI | | | | APPLICATION_CHARACTERISTIC | | | | FORM_CHARACTERISRIC | | | | BLOCK_CHARACTERISTIC | | | | FIELD_CHARACTERISTIC | | | |________________________________________________________________________|
Pachetul de functii NAME_IN returneaza continutul variabilei asupra careia e
aplicata. Daca fixezi functia NAME_IN formele SQL evalueaza toate functiile
individuale, de la cea plasata cel mai in interior pana la cea mai indepartata.
Nota: functia NAME_IN da functionalitate referintelor variabilelor
( '&variablename' ) in V2.
Sintaxa: NAME_IN ( nume_variabila | NAME_IN( localizare )) :GLOBAL.X := NAME_IN(:F); Cauta in F variabila cu o anumita valoare pentru a o copia in X. __________ ___________ __________ | | | | | | | A | | hello |-------->| hello | |__________| |___________| |__________| F A X
GO_BLOCK(NAME_IN('block.choice'));
IF NAME_IN( NAME_IN( 'golbal.saved_field'))='TKB SPORT SHOP' THEN NEXT_FIELD; END IF;In exemplul 2 functia NAME_IN din interior va fi evaluata prima.
APPLICATION_CHARACTERISTIC iti da posibilitatea de a gasi numele fisierului
formei curente sau numele formei care a apelat forma curenta.
Sintaxa: APPLICATION_CHARACTERISTIC( calling_form | current_form )
Exemplu: KEY-STARTUP ------------------------------------------------------------------ IF APPLICATION_CHARACTERISTIC(calling_form) IS NOT NULL THEN EXECUTE_QUERY; END IF;
Pachetul de functii FORM_CHARACTERISTIC furnizeaza numele primului sau
ultimului bloc din forma.
Sintaza: FORM_CHARACTERISTIC ( 'formname',primul_block/ultimul_bloc )
Pachetul de functii intoarce informatii cu privire la blocul
specificat.
Sintaxa: BLOCK_CHARACTERISTIC('nume_bloc',caracteristica) CARACTERISTICA INTOARCE: BASETABLE intoarce numele tabelului de baza sau zero ENTERABLE intoarce FALSE sau TRUE FIRST_FIELD intoarce numele primului camp LAST_FIELD intoarce numele ultimului camp NEXTBLOCK blocul urmator sau zero PREVIOUSBLOCK numele blocului anterior sau zero RECORD_DISPLAYED numarul de inregistrari pe care le poate afisa blocul TOP_RECORD numele primei inregistrari vizibile din blocExemple:
KEY-NXTFLD ------------------------------------------------------------------ IF :system.cursor_field = 'ORD.' || BLOCK_CHARACTERISTIC('ord', LAST_FIELD ) ELSE NEXT_FIELD; END IF; ------------------------------------------------------------------
Pachetul de functii FIELD_CHARACTERISTIC iti ofera posibilitatea de a specifica
una din cele 23 de caracteristici posibile si de a cere un atribut al unui
anumit camp. Valoarea obtinuta ca raspuns este sub forma unui sir de caractere.
Sintaxa: FIELD_CHARACTERISTIC('nume_camp', caracteristica )
FIELD_CHRACTERISTIC( :SYSTEM.CURSOR_FIELD, page ); | | | | | | --| |-- \ / \/ ANCHOR_VIEW( , 1, 1);
KEY-MENU on CUS block ------------------------------------------------------------------ default_value ('0', 'global.cpos'); :global.cpos := to_number(:global.cpos) + 1 ; if :global.cpos = 1 then anchor_view(3,1,1); elsif :global.cpos = 2 then anchor_view(3,40,1); elsif :global.cpos = 3 then anchor_view(3,1,15); elsif :global.cpos = 4 then anchor_view(3,40,15); :global.cpos :=0; end if; ------------------------------------------------------------------
-beep-aie cand tasta [Count Query Hits] este apasata -verifica daca atributul Automatic Hint a campului curent este apasata -daca da, sa o dezactiveze -daca nu, sa o activeze
KEY-DOWN on ITEM block --------------------------------------------------------------------- DOWN; IF :SYSTEM.RECORD_STATUS = 'NEW' THEN UP; END IF; ---------------------------------------------------------------------
ON-MESSAGE at FORM level --------------------------------------------------------------------- IF MESSAGE ('Your recordshave committed to the database'); ELSE MESSAGE(MESSAGE_TYPE||'-'||TO CHAR(MESSAGE_CODE)||':'|| MESSAGE_TEXT); END IF; ---------------------------------------------------------------------
a. Form-Level procedure WEEKEND_NOT_ALLOWED --------------------------------------------------------------------- PROCEDURE weekend_not _allowed ( field_name IN CHAR ) IS BEGIN IF TO_CHAR(TO_DATE(NAME_IN(field_name),'DD-MON-YY'), 'DY') IN ('SAT', 'SUN') THEN message('weekend dates not allowed in '|| field_name); raise from_trigger_failure; END IF; END; --------------------------------------------------------------------- b. ON-VALIDATE-FIELD on ORD.ORDERDATE --------------------------------------------------------------------- WEEKEND_NOT_ALLOWED( 'ORD.ORDERDATE') ---------------------------------------------------------------------
a. Form-level function PAGE_NUM --------------------------------------------------------------------- function PAGE_NUM return char is begin return(field_characteristic(:system.cursor_field,page)); end; --------------------------------------------------------------------- b. KEY-MENU on CUS Block --------------------------------------------------------------------- DEFAULT_VALUE ('0', 'GLOBAL.CPOS'); :GLOBAL_CPOS := TO_NUMBER(:GLOBAL.CPOS) + 1; IF :GLOBAL.CPOS = 1 THEN ANCHOR_VIEW(PAGE_NUM,1,1); ELSIF :GLOBAL.CPOS = 2 THEN ANCHOR_VIEW(PAGE_NUM,30,1); ELSIF :GLOBAL.CPOS = 3 THEN ANCHOR_VIEW(PAGE_NUM,30,10); ELSIF :GLOBAL.CPOS = 4 THEN ANCHOR_VIEW(PAGE_NUM,1,10); :GLOBAL.CPOS := 0; ENDIF; ---------------------------------------------------------------------
KEY-CQUERY --------------------------------------------------------------------- IF FIELD_CHARACTERISTIC (:SYSTEM.CURSOR_FIELD, AUTO_HELP) = 'TRUE' THEN SET_FIELD (:SYSTEM.CURSOR_FIELD, AUTO_HELP, ATTR_OFF); ELSE SET_FIELD (:SYSTEM.CURSOR_FIELD, AUTO_HELP, ATTR_ON); ENDIF; ---------------------------------------------------------------------