V príklade sú uvedené najpoužívanejšie príklady zápisu cyklov v PL SQL.
Popis príkladov:
1. WHILE/LOOP Cyklus s explicitným otvorením a zatvorením kurzora a prečítaním a výpisom všetkých riadkov do outputu.
2. Obdobný cyklus LOOP ako cyklus 1 s podmienkou na ukončenie pomocou klauzuly EXIT.
3. Obdobný cylkus ako cyklus 2 s pridaním vnoreného cyklu. Tu som ukázal možnosť použitia LABELov/návestí pre možnosť predčasného ukončenia cyklu.
4. Cyklus LOOP s inkrementom hodnoty prenennej I.
5. Cyklus FOR s využitím implicitného otvorenia a zatvorenia kurzora a prečítaním a výpisom všetkých riadkov do outputu.
6. Cylkus FOR s inkrementom hodnoty prenennej I a jej výpisom na output.
7. Cyklus FOR ALL som využil na update mena užívateľa na meno s veľkým začiatočným písmenom. Tento druh cyklu má niekoľko obmedzení v použití. Odporúčam pravidlá naštudovať v ORACLE dokumentácii.
Stačí zameniť svoju existujúcu tabuľku s jej s tĺpcami za tabuľku vo vašej schéme, kde budete testovať príklad a jednoducho anonymný blok spustíte na svojom klientovi.
Príklady som testoval na prostredí ORACLE 11g.
/* CYKLY V PL SQL */ SET SERVEROUTPUT ON DECLARE I INTEGER := 0; CUR1 SYS_REFCURSOR; CURSOR CUR2 IS SELECT USERNAME FROM USERS ORDER BY 1; CURSOR CUR3 IS SELECT USERNAME FROM USERS ORDER BY 1; USERNAME VARCHAR2(50); BEGIN DBMS_OUTPUT.PUT_LINE('CYCLE 1 START'); OPEN CUR1 FOR SELECT USERNAME FROM USERS ORDER BY 1; FETCH CUR1 INTO USERNAME; WHILE CUR1%FOUND LOOP DBMS_OUTPUT.PUT_LINE(USERNAME); FETCH CUR1 INTO USERNAME; END LOOP; CLOSE CUR1; DBMS_OUTPUT.PUT_LINE('CYCLE 1 FINISH'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE('CYCLE 2 START'); OPEN CUR2; LOOP FETCH CUR2 INTO USERNAME; EXIT WHEN CUR2%NOTFOUND; DBMS_OUTPUT.PUT_LINE(USERNAME); END LOOP; CLOSE CUR2; DBMS_OUTPUT.PUT_LINE('CYCLE 2 FINISH'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE('CYCLE 3 START'); OPEN CUR2; <<CYCLE1>> LOOP FETCH CUR2 INTO USERNAME; EXIT CYCLE1 WHEN CUR2%NOTFOUND; DBMS_OUTPUT.PUT_LINE('CYCLE 3 PART 1='||USERNAME); OPEN CUR3; <<CYCLE2>> LOOP FETCH CUR3 INTO USERNAME; EXIT CYCLE2 WHEN CUR3%NOTFOUND; DBMS_OUTPUT.PUT_LINE('CYCLE 3 PART 2='||USERNAME); /* possibility to finish cycle 1 IF .... THEN EXIT CYCLE1 WHEN ... any condition DBMS_OUTPUT.PUT_LINE(USERNAME); END IF; */ END LOOP CYCLE2 ; CLOSE CUR3; END LOOP CYCLE1; CLOSE CUR2; DBMS_OUTPUT.PUT_LINE('CYCLE 3 FINISH'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE('CYCLE 4 START'); I := 0; LOOP I := I + 1; DBMS_OUTPUT.PUT_LINE('I=' || TO_CHAR(I)); EXIT WHEN I = 10; END LOOP; DBMS_OUTPUT.PUT_LINE('CYCLE 4 FINISH'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE('CYCLE 5 START'); FOR JUSER IN (SELECT USERNAME FROM USERS ORDER BY 1) LOOP DBMS_OUTPUT.PUT_LINE('USERNAME=' || JUSER.USERNAME); END LOOP; DBMS_OUTPUT.PUT_LINE('CYCLE 5 FINISH'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE('CYCLE 6 START'); FOR I IN 1 .. 10 LOOP DBMS_OUTPUT.PUT_LINE('FOR I=' || TO_CHAR(I)); END LOOP; DBMS_OUTPUT.PUT_LINE('CYCLE 6 FINISH'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT_LINE('CYCLE 7 START'); DECLARE TYPE USERLIST IS VARRAY(2) OF INTEGER; USERSLIST USERLIST := USERLIST(); BEGIN USERSLIST(1) := 1; USERSLIST(2) := 2; FORALL I IN USERSLIST.FIRST..USERSLIST.LAST UPDATE USERS J SET J.USERNAME=INITCAP(J.USERNAME) WHERE J.IDUSER=USERSLIST(I); END; DBMS_OUTPUT.PUT_LINE('CYCLE 7 FINISH'); DBMS_OUTPUT.NEW_LINE; EXCEPTION WHEN OTHERS THEN IF CUR1%ISOPEN THEN CLOSE CUR1; END IF; IF CUR2%ISOPEN THEN CLOSE CUR2; END IF; IF CUR3%ISOPEN THEN CLOSE CUR3; END IF; END; /
Prajem vela efektívneho a bezchybného kódu.
S pozdravom