streda, 17 september 2014 10:27 Written by 2386 times
Rate this item
(2 votes)

PL/SQL - cykly

Ukážeme si zopár príkladov použitia rôznych druhov cyklov v PL SQL.

 

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

 

 

Last modified on streda, 17 september 2014 13:13
Alojz Benďák

Autor je administrátor webu a venuje sa programovaniu takmer 23 rokov.

  • prvý kontakt s počítačmi na strednej škole - PMD 1,2,3, PP06, Atari, Sinclair (programovanie v jazyku: strojový kód, basic a pascal):  2 roky
  • na VŠ - jazyky Turbo pascal a Turbo C: 1rok
  • programovanie databázového ekonomického širokoškálneho software v Delphi a C++ Borland (databázy Paradox): 8 rokov v Codex s.r.o. Nitra
  • programovanie webových aplikácií na databázach MySQL a MS SQL server: 1 roky na živnosť (firmy: Hermes Nitra, Schindler v Bratislave)
  • pracoval ako DBA v Homecredit Brno a vo VÚB Bratislava ako vyvojár + optimalizácie v SQL a PL/SQL na Oracle 11g (firma Accenture)
  • programoval programy pre súkromné firmy pre HW na skenovanie povrchov nádrží pre skladovanie tekutých palív (pristroj Leica)
  • momentálne pracuje ako DBA pod Oracle 11g a ako vyvojár vnútropodnikových databázových aplikacií v PHP, SQL, C++, C# a interface v PL/SQL: 11 rokov
  • ďalej programuje s HTML, CSS, Ajax, Javascript, VBA, MS visual C++ a C# malé podporné aplikácie
  • certifikát SQL expert for Oracle 11g   
  • spolupracuje a aktívne učí pre počítačové firmy: Lapis, IVIT v Nitre