Садржај
1 Релационе базе података
1.0 1 Релационе базе података
1.0 2 Релационе базе података - квиз
1.0 3 Веза један према више
1.0 4 Веза један према више - квиз
1.0 5 Веза више према више
1.0 6 Веза више према више - квиз
1.0 7 Алат за пројектовање
1.0 8 СУБП
1.0 9 Креирање базе на други начин
1.0 10 Још неке SQL команде
1.1 1 Упит SELECT
1.1 2 Упит SELECT - упит из једне табеле - задаци
1.1 3 Упит SELECT - упит из једне табеле - квиз
1.1 4 Упит SELECT - функције и подупити - задаци
1.1 5 Упит SELECT - функције и подупити - квиз
1.1 6 Упит SELECT - спајање - задаци
1.1 7 Упит SELECT - спајање - квиз
1.1 8 Упит SELECT - нерешени задаци
1.2 1 База података за библиотеку - креирање базе
1.2 2 БП Библиотека - Упит SELECT - упит из једне табеле - задаци
1.2 3 БП Библиотека - Упит SELECT - упит из једне табеле - нерешени задаци
1.2 4 БП Библиотека - Упит SELECT - спајање - задаци
1.2 5 БП Библиотека - Упит SELECT - спајање - нерешени задаци
1.2 6 БП Библиотека - Упит SELECT - функције и подупити - задаци
1.2 7 БП Библиотека - Упит SELECT - функције и подупити - нерешени задаци
1.3 1 База података за возачке дозволе - креирање базе
1.3 2 БП Возачке дозволе - Дијаграм и подаци - практичан рад
1.3 3 БП Возачке дозволе - Упит SELECT - задаци
1.3 4 БП Возачке дозволе - Упит SELECT - нерешени задаци
1.4 1 БП Филмови - Креирање базе - практични рад
1.4 2 БП Филмови - Дијаграм и подаци - практични рад
1.4 3 БП Филмови - Упит SELECT - задаци
1.4 4 БП Филмови - Упит SELECT - нерешени задаци
2 Писање програма унутар система за управљање базама података
2.0 1 Процедуре и команда INSERT
2.0 2 Процедуре и команде UPDATE и DELETE
2.0 3 Процедуре и команде INSERT, UPDATE, и DELETE - квиз
2.0 4 Процедуре и тестирање програма
2.0 5 Процедуре и упит SELECT
2.0 6 Процедуре и курсор за упит SELECT
2.1 1 Функције и упит SELECT
2.1 2 Процедуре и функције са упитом SELECT - квиз
2.1 3 Процедуре и функције са упитом SELECT из једне табеле - задаци
2.1 4 Процедуре и функције са упитом и групним функцијама - задаци
2.1 5 Процедуре и функције са упитом SELECT са спајањем табела - задаци
2.1 6 Процедуре и функције са упитом - нерешени задаци
2.1 7 Формат XML
2.2 1 База података за библиотеку - Процедуре, функције и поређење различитих решења
2.2 2 Процедуре, функције и поређење различитих решења
2.2 3 Процедуре и функције са упитом SELECT из једне табеле - вежбање
2.2 4 Процедуре и функције са упитом SELECT са спајањем табела - вежбање
2.2 5 Процедуре и функције са упитом и групним функцијама и подупитима - вежбање
2.2 6 Процедуре и функције са упитом SELECT - нерешени задаци
2.3 1 База података за возачке дозволе - процедуре и функције са упитом SELECT - вежбање
2.3 2 База података за возачке дозволе - процедуре и функције - нерешени задаци
2.4 1 База података за филмове - процедуре и функције са упитом SELECT - вежбање
2.4 2 База података за филмове - процедуре и функције - нерешени задаци
3 Писање програма у програмским језицима вишег нивоа
3.0 1 Писање програма у развојном окружењу Visual Studio
3.0 2 Писање програма у развојном окружењу Visual Studio - практичан рад
3.0 3 Писање програма у развојном окружењу Visual Studio - процедуре
3.0 4 Писање програма у развојном окружењу Visual Studio - квиз
3.1 1 Угнежђени упит SELECT унутар програма
3.1 2 Угнежђени упит SELECT унутар програма - задаци
3.1 3 Позив процедуре унутар програма
3.1 4 Позив креиране функције унутар програма
3.1 5 Програм са угнежђеним командама у развојном окружењу Visual Studio - квиз
3.1 6 Програм са угнежђеним упитом SELECT из једне табеле - вежбање
3.1 7 Програм са угњежђеним упитом и групним фунцкијама - вежбање
3.1 8 Програм са угнежђеним упитом SELECT са спајањем табела - вежбање
3.1 9 Програм са класом
3.1 10 Програм са угнежђеним упитом - нерешени задаци
3.1 11 Програм са угнежђеним командама INSERT, UPDATE, и DELETE
3.2 1 База података за библиотеку - програм са угнежђеним упитом SELECT из једне табеле - задаци
3.2 2 База података за библиотеку - програм са угнежђеним упитом SELECT - вежбање
3.2 3 База података за библиотеку - програм са угнежђеним упитом - нерешени задаци
3.3 1 База података за возачке дозволе - програм са угнежђеним упитом SELECT - вежбање
3.3 2 База података за возачке дозволе - програм са угнежђеним упитом - нерешени задаци
3.4 1 База података за филмове - програм са угнежђеним упитом SELECT - вежбање
3.4 2 База података за филмове - програм са угнежђеним упитом - нерешени задаци
4 Друга софтверска решења - СУБП Oracle
4.0 1 Oracle Apex и језик PL/SQL
4.0 2 Језик PL/SQL - задаци
4.0 3 Језик PL/SQL - квиз
4.0 4 Језик PL/SQL – нерешени задаци
4.0 5 Наредбе гранања
4.0 6 Наредбе гранања - нерешени задаци
4.0 7 Наредбе циклуса
4.0 8 Наредбе циклуса - нерешени задаци
4.1 1 База података за библиотеку - практичан рад
4.1 2 Наредба SELECT INTO
4.1 3 Наредба SELECT INTO - zadaci
4.1 4 Наредба SELECT INTO - квиз
4.1 5 Наредба SELECT INTO - вежбање
4.1 6 Наредба SELECT INTO - нерешени задаци
4.2 1 Курсори - Узимање података из више редова
4.2 2 Курсори - задаци
4.2 3 Различити начини да се реши проблем
4.2 4 Курсори - нерешени задаци
4.2 5 Курсор са параметром
4.2 6 Курсор са параметром - задаци
4.2 7 Курсор са параметром - нерешени задаци
4.2 8 Курсори - квиз
4.2 9 Курсори и гранање - задаци
4.2 10 Курсори - вежбање
4.2 11 Тренутне позајмице члана - пример
4.2 12 Спискови књига - пример
4.3 1 Процедуре и функције у СУБП-у Oracle Apex
4.3 2 Процедуре и функције - задаци
4.3 3 Процедуре и функције - нерешени задаци
4.3 4 Позајмице једне књиге - пример
4.3 5 Тренутне позајмице - пример
4.3 6 Процедуре и друге SQL команде
4.3 7 Тригери
4.3 8 Списак свих објеката у бази података
4.4 1 Креирање апликације помоћу алата App Builder
4.4 2 Додатне опције App Builder алата
4.4 3 Покретање апликације
4.4 4 Креирање нових страница у апликацији
4.4 5 Покретање раније креиране процедуре
4.4 6 Алат App Builder и XML
4.5 1 База података за салон аутомобила у СУБП-у Oracle Apex - 1. део
4.5 2 База података за салон аутомобила у СУБП-у Oracle Apex - 2. део
4.5 3 База података за салон аутомобила у СУБП-у Oracle Apex - 3. део
4.5 4 База података за продавницу - нерешени пројектни рад

Курсори - вежбање

Решити следеће задатке писањем програма у програмској језику PL/SQL. Приликом решавања задатака, погледајте претходно решене примере. Након што решите неки задатак па желите да проверите да ли је решење добро или видите да не можете да га решите, погледајте решење које ће се приказати након што кликнете на дугме.

Програми се пишу у едитору у оквиру онлајн окружења Oracle APEX, а покрећу се кликом на дугме Run:

Креирати PL/SQL програме који узимају податке из базе података библиотеке. Следи списак свих табела са колонама. Примарни кључеви су истакнути болд, а страни италик.

../_images/slika_73a.jpg
  1. Приказати укупан број позајмица за сваког члана библиотеке. Приказати и чланове који нису имали позајмице (користити спољно спајање).

Погледајмо прво упит којим ове податке узимамо из базе података.

--SELECT upit koji vraca ukupan broj pozajmica za svakog clana biblioteke
SELECT broj_clanske_karte, ime, prezime, COUNT(datum_uzimanja) AS broj
FROM clanovi LEFT OUTER JOIN pozajmice USING (broj_clanske_karte)
GROUP BY broj_clanske_karte, ime, prezime
../_images/slika_810a.jpg

Уколико би се изоставило спољно спајање LEFT OUTER, не би био приказан члан који није имао позајмице.

У програму ћемо креирати курсор који је везан за овај упит. Прво ћемо радити експлицитно са курсором. Приказиваћемо одговарајућу поруку уколико члан није позајмљивао књиге.

DECLARE
    CURSOR kursor_clanovi IS
        SELECT broj_clanske_karte, ime, prezime, COUNT(datum_uzimanja) AS broj
        FROM clanovi LEFT OUTER JOIN pozajmice USING (broj_clanske_karte)
        GROUP BY broj_clanske_karte, ime, prezime;
    v_clan kursor_clanovi%ROWTYPE;
BEGIN
    OPEN kursor_clanovi;
    LOOP
        FETCH kursor_clanovi INTO v_clan;
        EXIT WHEN kursor_clanovi%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_clan.broj_clanske_karte||' - '||v_clan.ime||' '||v_clan.prezime);
        IF v_clan.broj = 0 THEN
        DBMS_OUTPUT.PUT_LINE('  Clan nije pozajmljivao knjige');
        ELSE DBMS_OUTPUT.PUT_LINE('  Broj pozajmica: '||v_clan.broj);
        END IF;
    END LOOP;
    CLOSE kursor_clanovi;
END

Други приступ раду са курсором подразумева имплицитни облик рада и употребу циклуса FOR.

DECLARE
    CURSOR kursor_clanovi IS
        SELECT broj_clanske_karte, ime, prezime, COUNT(datum_uzimanja) AS broj
        FROM clanovi LEFT OUTER JOIN pozajmice USING (broj_clanske_karte)
        GROUP BY broj_clanske_karte, ime, prezime;
        v_clan kursor_clanovi%ROWTYPE;
BEGIN
    FOR v_clan IN kursor_clanovi LOOP
    DBMS_OUTPUT.PUT_LINE(v_clan.broj_clanske_karte||' '||v_clan.ime||' '||v_clan.prezime);
        IF v_clan.broj = 0 THEN
        DBMS_OUTPUT.PUT_LINE('  Clan nije pozajmljivao knjige');
        ELSE
        DBMS_OUTPUT.PUT_LINE('  Broj pozajmica: '||v_clan.broj);
        END IF;
    END LOOP;
END
../_images/slika_810b.jpg

У наредном задатку, који је сличан, приказаћемо други начин да се приступи решавању овог проблема, а без спајања табела, без потребе да водимо рачуна о спољном спајању, и без употребе GROUP BY.

  1. Приказати број текућих позајмица за сваког члана библиотеке.

У овом решењу задатка, који је веома сличан претходном, имамо другачији приступ. Курсором идемо кроз списак свих чланова, а за сваког члана наредбом SELECT INTO узмемо број његових позајмица.

DECLARE
    CURSOR kursor_clanovi IS
        SELECT * FROM clanovi;
    broj NUMBER(3);
BEGIN
    FOR v_clan IN kursor_clanovi LOOP
    DBMS_OUTPUT.PUT_LINE(v_clan.broj_clanske_karte||' - '||v_clan.ime||' '||v_clan.prezime);
        DBMS_OUTPUT.PUT_LINE('Telefon: '||v_clan.telefon);
        DBMS_OUTPUT.PUT_LINE('Mejl: '||v_clan.mejl_adresa);
        SELECT COUNT(*) INTO broj
        FROM pozajmice WHERE broj_clanske_karte=v_clan.broj_clanske_karte
        AND datum_vracanja IS NULL;
        IF broj = 0 THEN
        DBMS_OUTPUT.PUT_LINE('  Nema tekucih pozajmica');
        ELSE
        DBMS_OUTPUT.PUT_LINE('  Broj tekucih pozajmica: '||broj);
        END IF;
    END LOOP;
END
../_images/slika_810c.jpg.jpg
  1. Приказати све позајмице за члана библиотеке са бројем чланске карте 33.

Задатак може да се реши и без употребе курсора са параметром.

DECLARE
    CURSOR kursor_pozajmice (p_broj_clanske_karte clanovi.broj_clanske_karte%TYPE) IS
        SELECT naziv, datum_uzimanja, datum_vracanja
        FROM pozajmice JOIN primerci USING (inventarski_broj)
        JOIN knjige USING (id_knjige)
        WHERE broj_clanske_karte = p_broj_clanske_karte;
BEGIN
    FOR v_pozajmica IN kursor_pozajmice(33) LOOP
        DBMS_OUTPUT.PUT_LINE('  '||v_pozajmica.naziv||' - '||v_pozajmica.datum_uzimanja||
        ' - '||v_pozajmica.datum_vracanja);
    END LOOP;
END
  1. Приказати све позајмице за сваког члана библиотеке.

DECLARE
    CURSOR kursor_clanovi IS
        SELECT * FROM clanovi;
    CURSOR kursor_pozajmice (p_broj_clanske_karte clanovi.broj_clanske_karte%TYPE) IS
        SELECT naziv, datum_uzimanja, datum_vracanja
        FROM pozajmice JOIN primerci USING (inventarski_broj)
        JOIN knjige USING (id_knjige)
        WHERE broj_clanske_karte = p_broj_clanske_karte;
BEGIN
    FOR v_clan IN kursor_clanovi LOOP
    DBMS_OUTPUT.PUT_LINE(v_clan.broj_clanske_karte||' - '||v_clan.ime||' '||v_clan.prezime);
        DBMS_OUTPUT.PUT_LINE('Telefon: '||v_clan.telefon);
        DBMS_OUTPUT.PUT_LINE('Mejl: '||v_clan.mejl_adresa);

        FOR v_pozajmica IN kursor_pozajmice(v_clan.broj_clanske_karte) LOOP
            DBMS_OUTPUT.PUT_LINE('  '||v_pozajmica.naziv||' - '||v_pozajmica.datum_uzimanja||
            ' - '||v_pozajmica.datum_vracanja);
            END LOOP;
    END LOOP;
END
../_images/slika_810d.jpg
  1. Приказати списак свих тренутних позајмица уређен од оних књига које су најдуже издате до најскоријих позајмица.

DECLARE
    CURSOR spisak_pozajmica IS
    SELECT broj_clanske_karte, ime, prezime, knjige.naziv, datum_uzimanja from clanovi
    JOIN pozajmice USING (broj_clanske_karte)
    JOIN primerci USING (inventarski_broj)
    JOIN knjige USING (id_knjige)
    WHERE datum_vracanja IS NULL
    ORDER BY datum_uzimanja;
    v_red spisak_pozajmica%rowtype;
BEGIN
    OPEN spisak_pozajmica;
    LOOP
        FETCH spisak_pozajmica INTO v_red;
        EXIT WHEN spisak_pozajmica%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(v_red.broj_clanske_karte||' - '||v_red.ime||' '||v_red.prezime);
        DBMS_OUTPUT.PUT_LINE(' '||v_red.naziv||'; '||v_red.datum_uzimanja);
    END LOOP;
    CLOSE spisak_pozajmica;
END

Други приступ раду са курсором подразумева имплицитни облик рада и употребу циклуса FOR.

DECLARE
    CURSOR spisak_pozajmica IS
    SELECT broj_clanske_karte, ime, prezime, knjige.naziv, datum_uzimanja from clanovi
    JOIN pozajmice USING (broj_clanske_karte)
    JOIN primerci USING (inventarski_broj)
    JOIN knjige USING (id_knjige)
    WHERE datum_vracanja IS NULL
    ORDER BY datum_uzimanja;
BEGIN
    FOR v_red IN spisak_pozajmica LOOP
        DBMS_OUTPUT.PUT_LINE(v_red.broj_clanske_karte||' - '||v_red.ime||' '||v_red.prezime);
        DBMS_OUTPUT.PUT_LINE(' '||v_red.naziv||'; '||v_red.datum_uzimanja);
    END LOOP;
END
  1. За унет назив издавача, приказати све контакт информације чланова библиотеке који су читали књиге тог издавача.

DECLARE
    CURSOR spisak_clanova (p_naziv izdavaci.naziv%TYPE) IS
    SELECT DISTINCT ime, prezime, broj_clanske_karte, mejl_adresa FROM pozajmice
    JOIN clanovi USING (broj_clanske_karte)
    JOIN primerci USING (inventarski_broj)
    JOIN knjige USING (id_knjige)
    JOIN izdavaci ON izdavaci.id = id_izdavaca
    WHERE izdavaci.naziv = p_naziv;
    v_naziv izdavaci.naziv%TYPE;
BEGIN
    v_naziv := :naziv;
    FOR clan IN spisak_clanova(v_naziv) LOOP
        DBMS_OUTPUT.PUT_LINE('Broj clanske karte: ' || clan.broj_clanske_karte);
        DBMS_OUTPUT.PUT_LINE(' ' || clan.ime || ' ' || clan.prezime || ' - ' ||
        clan.mejl_adresa);
    END LOOP;
END
  1. За сваког члана који је имао позајмице, приказати списак издавача књига које је читао.

DECLARE
    v_br_pozajmica NUMBER(10);
    CURSOR spisak_clanova IS SELECT broj_clanske_karte, ime, prezime FROM clanovi;
    CURSOR spisak_izdavaca(p_broj_clanske_karte pozajmice.broj_clanske_karte%TYPE) IS
    SELECT DISTINCT izdavaci.naziv FROM izdavaci
    JOIN knjige ON (id = id_izdavaca)
    JOIN primerci USING (id_knjige)
    JOIN pozajmice USING (inventarski_broj)
    WHERE pozajmice.broj_clanske_karte=p_broj_clanske_karte;
BEGIN
    FOR v_clan IN spisak_clanova LOOP
        DBMS_OUTPUT.PUT_LINE('Ime i prezime clana: ' || v_clan.ime ||' '|| v_clan.prezime);
        DBMS_OUTPUT.PUT_LINE('Broj clanske karte: ' || v_clan.broj_clanske_karte);
        SELECT COUNT(*) INTO v_br_pozajmica
        FROM pozajmice WHERE v_clan.broj_clanske_karte = broj_clanske_karte;
        IF v_br_pozajmica = 0 THEN
            DBMS_OUTPUT.PUT_LINE('Clan nije imao pozajmica');
        ELSE
            DBMS_OUTPUT.PUT_LINE('Broj pozajmica: ' || v_br_pozajmica);
            FOR v_izdavac in spisak_izdavaca(v_clan.broj_clanske_karte) LOOP
            DBMS_OUTPUT.PUT_LINE('  Naziv izdavaca: ' || v_izdavac.naziv);
            END LOOP;
        END IF;
    END LOOP;
END;

Део резултата рада програма може да се види на следећој слици.

../_images/slika_810c.jpg
  1. За сваког запосленог приказати списак свих позајмица за које је био задужен.

DECLARE
    CURSOR spisak_zaposlenih IS SELECT id, ime, prezime FROM zaposleni;
    CURSOR spisak_pozajmica(p_id_zaposlenog zaposleni.id%TYPE)
    IS SELECT inventarski_broj, broj_clanske_karte, datum_uzimanja
    FROM pozajmice WHERE id_zaposlenog=p_id_zaposlenog;
BEGIN
    FOR v_zaposleni IN spisak_zaposlenih LOOP
            DBMS_OUTPUT.PUT_LINE('Ime i prezime:' || v_zaposleni.ime || ' ' ||
            v_zaposleni.prezime);
        FOR v_pozajmica IN spisak_pozajmica(v_zaposleni.id) LOOP
            DBMS_OUTPUT.PUT_LINE('  Inventarski broj:' || v_pozajmica.inventarski_broj);
            DBMS_OUTPUT.PUT_LINE('  Broj clanske karte:' || v_pozajmica.broj_clanske_karte);
            DBMS_OUTPUT.PUT_LINE('  Datum uzimanja:' || v_pozajmica.datum_uzimanja);
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('   ');
    END LOOP;
END
  1. За члана који је дошао у библиотеку, према његовом броју чланске карте, приказати списак свих књига свих аутора чију је бар једну књигу прочитао.

DECLARE
    CURSOR spisak_knjiga(p_broj_clanske_karte clanovi.broj_clanske_karte%TYPE)
        IS SELECT naziv, ime||' '||prezime AS autor
        FROM knjige JOIN autori_knjige ON (autori_knjige.id_knjige=knjige.id_knjige)
        JOIN autori ON (autori_knjige.id_autora=autori.id_autora)
        WHERE autori.id_autora IN (SELECT autori.id_autora
        FROM pozajmice JOIN primerci
        ON (pozajmice.inventarski_broj=primerci.inventarski_broj)
        JOIN knjige ON (primerci.id_knjige=knjige.id_knjige)
        JOIN autori_knjige ON (autori_knjige.id_knjige=primerci.id_knjige)
        WHERE broj_clanske_karte=p_broj_clanske_karte);
    v_broj_clanske_karte clanovi.broj_clanske_karte%TYPE;
BEGIN
    v_broj_clanske_karte := :broj_cl_karte;
    FOR knjiga IN spisak_knjiga(v_broj_clanske_karte) LOOP
        DBMS_OUTPUT.PUT_LINE('Naziv knjige: '||knjiga.naziv);
        DBMS_OUTPUT.PUT_LINE(' Ime autora: '||knjiga.autor);
    END LOOP;
END
(Created using Swinx, RunestoneComponents and PetljaDoc)
© 2022 Petlja
A- A+