|
Politica de confidentialitate |
|
• domnisoara hus • legume • istoria unui galban • metanol • recapitulare • profitul • caract • comentariu liric • radiolocatia • praslea cel voinic si merele da aur | |
Structuri de control - Oracle | ||||||
|
||||||
k4y19ye In acest capitol se explica structurile de control ale unui program PL/SQL. Acestea sint expresiile conditionale, salturile si buclele. Introducere in expresiile de control ale PL/SQL PL/SQL ofera facilitati de control al executiei conditionat si neconditionat. Aceste sint: instructiuneaIF Ofera controlul selectiv al actiunilor, bazat pe indeplinirea unor conditii. instructiunea GOTO Se foloseste la saltul neconditionat la o eticheta din program. ciclul simplu Asigura repetarea unor actiuni fara impunerea de conditii ciclul FOR Pentru control iterativ al actiunilor, bazat pe un contor. cicluri WHILE Pentru control iterativ al actiunilor, bazat pe indeplinrea unei conditii instructiunea EXIT Pentru a iesi dintr-un ciclu Acolo unde aceste facilitati includ o conditie, aceasta poate fi orice expresie booleana valida in SQL, cu exceptia query imbricat. Aceasta include: Operatori logici ( ,, -, NOT, etc.) Operatori de compunere ( AND, OR ) Operatori SQL ( LIKE, IN, BETWEEN, IS NULL ) Exemple: var <= var2 var3 LIKE '%S%' var4 BETWEEN '01-JUN-92' AND '01-SEP-92' var2 IS NOT NULL bool_var x IN ( 'Y', 'N', 'YES', 'NO' ) ( a = b OR c = 5 ) AND p < 400 Instructiunea IFInstructiunea IF are o structura similara cu echivalentul din limbajele procedurale. Ea permite executarea unor actiuni selectiv, bazat pe indeplinirea unor conditii. Structura sa generala este prezentata mai jos. Sintaxa: IF conditie THEN actiuni a ELSIF conditie THEN actiuni i a ELSE actiuni i END IF; unde "actiuni" pot fi una sau mai multe instructiuni PL/SQL sau SQL,
fiecare terminata cu punct-virgula. Aceste "actiuni" pot include alte
instructiuni IF cu aceiasi structura, ceea ce inseamna ca instruciunea poate
contine IF, ELSE, ELSIF imbricate. IF v_ename = 'SCOTTY' THEN beam_me_up := 'YES'; COMMIT; END IF; Cele doua actiuni sind executate numai daca conditia este adevarata (TRUE). Daca conditia este falsa (FALSE sau NULL) atunci cele doua instructiuni sint excluse. In oricare din caz, executia continua cu urmatoarea instructiune din program de dupa END IF.Notati ca daca constructia 'END IF' nu este prezenta la sfirsitul instructiunii, atunci PL/SQL ca cauta in instructiunile urmatoare cautind 'END IF'. Ca si in alte limbaje procedurale aceasta poate provoca afisarea unor mesaje de eroare confuze. Urmatorul exemplu arata cum pot fi executate instructiuni alternative prin intermediul clauzei ELSE. Actiunile specificate prin ELSE sint executate daca conditiila este FALSE sau NULL, dupa care programul continua cu instructiunile ce urmeaza dupa END IF. IF ename = 'SCOTTY' THEN beam_me_up = 'YES' ; COMMIT; ELSE beam_me_up = 'NO' ; ROLLBACK; END IF; Oricare set de actiuni poate include instructiuni IF inlantuite pentru a executa teste ulterioare inainte ca o actiune specifica sa fie executata. Fiecare instructiune IF inlantuita trebuie sa fie terminata de END IF-ul corespunzator. Exemplu: IF deptno = 10 THEN accounting := 'YES';IF job = 'MANAGER' THEN INSERT INTO status VALUES ( ' Dept10 Manager'); END IF; COMMIT; ELSE accounting := 'NO'; IF job = 'MANAGER' THEN INSERT INTO status VALUES (' Alt Mgr.'); END IF; COMMIT; END IF; Adesea, actiunile de executat in clauza ELSIF pot contine doar un alt IF. In aceasta situatie, este mult mai convenabil sa folositi clauza ELSIF, care elimina necesitatea de a inlantui END IF la sfirsitul fiecarui set ulterior de conditii/actiuni: IF f_title = 'doamna' THEN status := 'MARITATA'; ELSIF f_title = 'domnisoara' THEN status := 'NEM.' ELSE status:= 'NECUNOSCUTA'; END IF; Datorita posibilitatii de a imbrica actiuni, clauza ELSIF poate fi utilizata recursiv, daca doriti:IF choise = 1 THEN actiune := 'Run Payroll' ; ELSIF choice = 2 THEN actiune := 'Run Accounts'; ELSIF choice = 3 THEN actiune := 'Backups'; ELSIF choice = 4 THEN actiune := 'Restore'; ELSE actiune := 'Invalid'; END IF; ------------------------------------------------------------------------------- Cicluri de baza si instructiunea EXIT -- actiuni de executat in -- cadrul ciclului END LOOP; * EXIT termina ciclul Sintaxa: EXIT aeticheta-ciclui aWHEN conditiei;-------------------------------------------------------------------------------- Cicluri si salturi in PL/SQL LOOP -- actiuni de executat -- in cadrul ciclului END LOOP; De fiecare data cind programul ajunge la constructia END LOOP, controlul este redat expresiei LOOP corespunzatoare. Acest ciclu necontrolat va fi, bineinteles, infinit daca nu se folosesc instructiuni de control in interiorul ciclului, care sa provoace saltul in afara ciclului.Instructiunea EXIT Un ciclu poate fi terminat din interior, daca este utilizata instructiunea EXIT. EXIT permite transferul controlului instructiunii urmatoare de dupa END LOOP, permitind astfel incheierea imediata a ciclului. Sintaxa: EXIT aloop-labeli aWHEN conditiei; EXIT poate fi executat fie ca o actiune dintr-un IF, sau ca o instructiune individuala in cadrul unui ciclu. In acest caz, o clauza WHEN poate fi atasata la instructiunea IF, permitind terminarea conditionata a ciclului. Exemplul 1: LOOP counter := counter + 1; INSERT INTO numbered_rows VALUES (counter); ... IF counter = 10 THEN COMMIT; EXIT; END IF; END LOOP; Exemplul 2: LOOP... EXIT WHEN total_sals = 60000; ... END LOOP; O alta posibilitate de a iesi dintr-un ciclu ar fi sa sariti la o instructiune etichetata in afara ciclului, folosind instructiunea GOTO. Aceasta este in general considerata ca o metoda mai putin structurata. GOTO si etichetele vor fi discutate mai tirziu, in acest capitol.Utilizarea ciclurilor FOR pentru controlul iteratiilor Sintaxa: FOR variabila_control IN aREVERSEi valoare_inferioare .. valoare_superioara Unde 'variabila_control' este numele unei variabile intregi ale carei valori vor fi incrementate/decrementate automat la fiecare iteratie a ciclului. Aceasta variabila este creata de catre ciclu, si nu poate fi scrisa de nici o instructiune din cadrul ciclului. Durata de viata se termina la terminarea ciclului.'valoare_inferioara' si 'valoare_superioar' sint expresii intregi, care determina valorile pe care le va lua variabila de control. Implicit, variabila de control este initializata cu o valoare mica, si este incrementata cu +1 la fiecare iteratie pina cind valoarea superioara este atinsa. Exemplu: FOR i IN 1 .. 2000LOOP INSEERT INTO numbered_rows VALUES (i); preserve_i := i; ... END LOOP; Observati ca daca valoarea lui 'i' este necesara dupa terminarea ciclului, atunci ea trebuie copiata intr-o variabila declarata inainte de terminarea ciclului.Ciclul FOR poate si sa decrementeze variabila de control, incepind de la valoarea superioara in prima iteratie: FOR n IN REVERSE 50 .. myvar+50LOOP -- n are valoarea myvar+50 la prima iteratie. -- si valoarea 50 la ultima END LOOP; Utilizarea ciclurilor WHILE pentru controlul iteratiilorAceasta este o structura de control alternativa, care permite iteratiilor sa fie executate conditionat. Sintaxa: WHILE conditie Conditia este evaluata la inceputul fiecarei iteratii, si ciclul este terminat cind conditia este FALSE. Daca conditia este FALSE atunci cind ciclul incepe, atunci nici o interatie nu se executa.Exemplul 1: WHILE bill <250 AND food LIKE '%taco%'LOOP -- actiuni END LOOP; Exemplul 2: WHILE bool_varLOOP -- actiuni END LOOP; Normal, daca variabila implicata in conditii nu se schimba in timpul executiei ciclului, atunci ciclul nu se va termina niciodata. Totusi instructiunea EXIT poate fi inclusa atit in ciclurile FOR si WHILE.Controlul ciclurilor imbricate Etichetele in PL/SQL sint definite astfel: << label-name >> Numele etichetei urmeaza aceleasi reguli ca si orice identificatori. O eticheta este plasata inaintea unei instructiuni, fie pe aceasi linie, fie pe o linie separata.Ciclurile pot fi etichetate prin plasatea unei etichete inainte de cuvintul LOOP, si dupa END LOOP, conform: << outer_limits >> LOOP-- actiuni END LOOP outer_limits; Daca un ciclu subordonat executa un EXIT, atunci el poate specifica care ciclu sa fie incheiat prin specificarea etichetei.Exemplu: << main >> LOOP... LOOP ... EXIT main WHEN total_done = 'YES'; -- paraseste ambele cicluri EXIT WHEN inner_done = 'YES'; -- paraseste doar ciclul interior END LOOP main; Folosirea GOTO si a etichetelorDupa cum ati vazut, etichetele pot fi utilizate pentru a identifica cicluri atunci cind apar in structuri inlantuite. Aceasta este si cazul blocurilor inlantuite. O eticheta poate fi plasata inaintea inceputului si dupa sfirsitul unui bloc PL/SQL, astfel incit identitatea sa declarate sa poate fi deosebita de celelalte blocuri din structura inlantuita. Sa luam exemplul urmator: DECLARE var1 NUMBER; BEGIN . DECLARE var1 NUMBER := 400; BEGIN . var1 := var1 + 1 ; -- var1 din subbloc se mareste cu 1 . END; . END; Variabila var1 care a fost declarata in blocul exterior nu se "vede" in cadrul blocului interior, deoarece acesta a declarat o variabila cu acelasi nume. Toate referirile la 'var1' din sub-bloc vor fi deci folosite pentru variabila local declarata.Totusi, daca blocurile sint etichetate, identificatorii pot fi referiti prefixati de numele blocului dorit. (Observatie: blocul exterior nu trebuie neaparat etichetat). Un exemplu: BEGIN<> DECLARE var1 NUMBER; . BEGIN . <> DECLARE var1 NUMBER := 400; BEGIN . block1.var1 := block1.var + 1; -- variabila din block 1 -- este incrementata END block2; END block1; END; Asa cum s-a aratat, END poate include numele blocului care trebuie terminat.Instructiunea GOTO Valabilitatea unei etichete este in intregul bloc in care a fost definita. GOTO poate, deci, transmite controlul catre puncte etichetate din blocul curent sau catre un punct etichetat dintr-un alt bloc care contine blocul curent. Sintaxa: GOTO eticheta; Unde 'eticheta' poate fi orice eticheta care marcheaza o pozitie in cadrul blocului curent sau al altuia ce il cuprinde. GOTO nu poate transmite controlul in interiorul unui sub-bloc.Exercitii pentru capitolul 22 UPDATE messages SET numcol2 = 100 WHERE numcol1 = V ; Daca rularea UPDATE produce altceva decit un singur rind, atunci se va iesi din ciclu.( Puteti testa atributul SQL%ROWCOUNT, asa cum este discutat in capitolul 23).Solutii la capitolul 22 BEGIN FOR v_count IN 1..10 LOOP IF v_count NOT IN (6,8) THEN INSERT INTO messages (numcol1) VALUES (v_count); END IF; END LOOP; COMMIT; END; DECLARE v_ename emp.ename%TYPE; v_hiredate emp.hiredate%TYPE; v_sal emp.sal%TYPE; v_message CHAR(30); BEGIN SELECT ename, hiredate, sal INTO v_ename, v_hiredate, v_sal FROM emp WHERE empno = &EMPLOYEE_NO ; IF v_sal > 1200 THEN v_message := 'Salariu mai mare de 1200'; ELSIF v_ename LIKE '%T%' THEN v_message := 'Numele contine "T"'; ELSIF TO_CHAR(v_hiredate, 'MON') = 'DEC' THEN v_message := 'Decembrie'; ELSE v_message := '** Nimic **'; END IF; INSERT INTO messages (charcol1) values (v_message); END; BEGIN FOR v IN 1 .. 10 LOOP UPDATE messages SET numcol2 = 100 WHERE numcol1 = v; EXIT WHEN SQL%ROWCOUNT <> 1; END LOOP; END; |
||||||
|
||||||
|
||||||
Copyright© 2005 - 2025 | Trimite document | Harta site | Adauga in favorite |
|