Садржај
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_92a.jpg
  1. Написати функцију која враћа све податке о запосленом на основу идентификационог броја.

CREATE OR REPLACE FUNCTION zaposleni_fja(p_id zaposleni.id%TYPE)
RETURN zaposleni%ROWTYPE AS
    podaci zaposleni%ROWTYPE;
BEGIN
    SELECT * INTO podaci FROM zaposleni
    WHERE id=p_id;
    RETURN podaci;
END
../_images/slika_92b.jpg

Након што је креирана и сачувана, функцију можемо да позовемо у програму. У програму који следи, функцију позивамо за запосленог са идентификационим бројем 2.

DECLARE
    v_zaposleni zaposleni%ROWTYPE;
BEGIN
    v_zaposleni := zaposleni_fja(2);
    DBMS_OUTPUT.PUT_LINE('Zaposleni: '||v_zaposleni.prezime||' '||v_zaposleni.ime);
    DBMS_OUTPUT.PUT_LINE('Mejl: '||v_zaposleni.mejl);
    DBMS_OUTPUT.PUT_LINE('Plata: '||v_zaposleni.plata||' RSD');
END

Функцију можемо да позовемо и тако да се приказују подаци за све запослене.

DECLARE
    CURSOR spisak_zaposlenih IS SELECT id FROM zaposleni;
    v_zaposleni zaposleni%ROWTYPE;
BEGIN
    FOR v_red IN spisak_zaposlenih LOOP
        v_zaposleni := zaposleni_fja(v_red.id);
    DBMS_OUTPUT.PUT_LINE('Zaposleni: '||v_zaposleni.prezime||' '||v_zaposleni.ime);
    DBMS_OUTPUT.PUT_LINE('Mejl: '||v_zaposleni.mejl);
    DBMS_OUTPUT.PUT_LINE('Plata: '||v_zaposleni.plata||' RSD');
    END LOOP;
END
  1. Написати процедуру која приказује име, презиме и телефон за сваког члана библиотеке

Ова процедура нема параметре.

CREATE OR REPLACE PROCEDURE telefoni_clanova AS
    CURSOR kursor_clan IS SELECT ime, prezime, telefon FROM clanovi;
BEGIN
    FOR clan IN kursor_clan LOOP
        DBMS_OUTPUT.PUT_LINE('Ime i prezime clana: '||clan.ime||' '||clan.prezime);
        DBMS_OUTPUT.PUT_LINE('Telefon: '|| clan.telefon);
    END LOOP;
END

Након што је креирана и сачувана, процедуру можемо да позовемо у програму.

BEGIN
    telefoni_clanova;
END

База података за библиотеку коју користимо нема превелики број података. Најчешће у базама имамо табеле са веома великим бројем редова и није могуће да све податке из табеле повучемо у програм. Из тог разлога можемо да ограничимо број редова из којих узимамо податке користећи у упиту FETCH FIRST ROWS ONLY уз навођење броја редова који нам је потребан.

Следи измењена процедура која узима број чланова чије ћемо податке приказати.

Како је пример базе података за библиотеку мали, ово нећемо употребљавати у програмима који следе, али би требало да увек имате у виду да се FETCH FIRST ROWS ONLY, или нека друга опција за ограничавање броја редова који се узимају, обавезно користи у већим базама података.

CREATE OR REPLACE PROCEDURE telefoni_clanova(broj INT) AS
    CURSOR kursor_clan IS SELECT ime, prezime, telefon FROM clanovi
    FETCH FIRST broj ROWS ONLY;
BEGIN
    FOR clan IN kursor_clan LOOP
        DBMS_OUTPUT.PUT_LINE('Ime i prezime clana: '||clan.ime||' '||clan.prezime);
        DBMS_OUTPUT.PUT_LINE('Telefon: '|| clan.telefon);
    END LOOP;
END

Следећи позив процедуре приказује телефоне само три члана.

BEGIN
    telefoni_clanova(3);
END
  1. Написати функцију која рачуна просечну плату свих запослених у библиотеци.

Ова функција нема параметре.

CREATE OR REPLACE FUNCTION prosecna_plata RETURN NUMBER AS
    v_iznos NUMBER;
BEGIN
    SELECT ROUND(AVG(plata),2) INTO v_iznos FROM zaposleni;
    RETURN v_iznos;
END

Након што је креирана и сачувана, функцију можемо да позовемо у програму. У овом примеру, вредност коју је функција израчунала приказујемо на екрану директно у позиву процедуре PUT_LINE.

BEGIN
    DBMS_OUTPUT.PUT_LINE(prosecna_plata);
END

У програму у којем позивамо функцију смо могли и да декларишемо и употребимо променљиву.

DECLARE
    v_prosek NUMBER;
BEGIN
    v_prosek := prosecna_plata;
    DBMS_OUTPUT.PUT_LINE(v_prosek);
END
  1. Написати функцију која рачуна просечну плату свих запослених у библиотеци чији менаџер има дати идентификациони број.

CREATE OR REPLACE FUNCTION
    prosecna_plata_po_menadzeru(p_id zaposleni.id_menadzera%TYPE) RETURN NUMBER AS
    v_iznos NUMBER;
BEGIN
    SELECT ROUND(AVG(plata),2) INTO v_iznos FROM zaposleni
    WHERE id_menadzera = p_id;
    RETURN v_iznos;
END

Након што је креирана и сачувана, функцију можемо да позовемо у програму. У програму који следи, функцију позивамо за менаџера са идентификационим бројем 1.

BEGIN
    DBMS_OUTPUT.PUT_LINE(prosecna_plata_po_menadzeru(1));
END

Функцију можемо да позовемо и у програму тако да се за сваког менаџера прикажу просечне плате запослених који раде код њега у тиму. Нису сви запослени менаџери. Да бисмо добили само оне запослене који су менаџери, потребно је да погледамо колону id_menadzera у табели zaposleni. Како један менаџер често управља тимом који има више запослених, његов идентификациони број ће се више пута појавити у овој колони, па је неопходно употребити DISTINCT када издвајамо списак идентификационих бројева менаџера. Уколико неко од запослених нема менаџера, код њега ће писати null у колони id_menadzera, па је са овог списка важно уклонити null.

DECLARE
    CURSOR spisak_menadzera IS
        SELECT DISTINCT id_menadzera FROM zaposleni WHERE id_menadzera IS NOT NULL;
    v_ime zaposleni.ime%TYPE;
    v_prezime zaposleni.prezime%TYPE;
BEGIN
    FOR v_red IN spisak_menadzera LOOP
        SELECT ime, prezime INTO v_ime, v_prezime FROM zaposleni
        WHERE id=v_red.id_menadzera;
        DBMS_OUTPUT.PUT_LINE('Menadzer: '||v_ime||' '||v_prezime);
        DBMS_OUTPUT.PUT_LINE('Prosecna plata u timu: ');
        DBMS_OUTPUT.PUT_LINE(prosecna_plata_po_menadzeru(v_red.id_menadzera)||' RSD');
    END LOOP;
END
  1. Написати процедуру која приказује све позајмице за сваког члана. Приказати датум и назив позајмљене књиге.

CREATE OR REPLACE PROCEDURE spisak_pozajmica AS
    CURSOR kursor_clan
        IS SELECT broj_clanske_karte, ime||' '||prezime clan, telefon FROM clanovi;
    CURSOR kursor_pozajmica (p_broj_clanske_karte clanovi.broj_clanske_karte%TYPE)
        IS SELECT datum_uzimanja, naziv
        FROM pozajmice JOIN primerci USING (inventarski_broj)
        JOIN knjige USING (id_knjige) WHERE broj_clanske_karte=p_broj_clanske_karte;
BEGIN
    FOR v_red_clan IN kursor_clan LOOP
        DBMS_OUTPUT.PUT_LINE('Ime i prezime clana: '||v_red_clan.clan);
        DBMS_OUTPUT.PUT_LINE('Telefon: '|| v_red_clan.telefon);
        FOR v_red_pozajmica IN kursor_pozajmica(v_red_clan.broj_clanske_karte) LOOP
        DBMS_OUTPUT.PUT_LINE('   Datum pozajmice: '||v_red_pozajmica.datum_uzimanja);
        DBMS_OUTPUT.PUT_LINE('   Naziv knjige: '||v_red_pozajmica.naziv);
        END LOOP;
    END LOOP;
END

Након што је креирана и сачувана, процедуру можемо да позовемо у програму.

BEGIN
    spisak_pozajmica;
END

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

../_images/slika_92c.jpg
  1. Написати процедуру која за дати идентификациони број издавача приказује све књиге тог издавача и број примерака сваке од тих књига у библиотеци.

CREATE OR REPLACE PROCEDURE spisak_knjiga(p_id_izdavaca izdavaci.id%TYPE) AS
    CURSOR kursor_knjige
        IS SELECT knjige.naziv AS naziv, COUNT(inventarski_broj) AS broj_primeraka
        FROM knjige JOIN primerci USING (id_knjige) WHERE id_izdavaca = p_id_izdavaca
        GROUP BY knjige.naziv;
BEGIN
    FOR v_red_knjiga IN kursor_knjige LOOP
        DBMS_OUTPUT.PUT_LINE('Naziv knjige: '||v_red_knjiga.naziv);
        DBMS_OUTPUT.PUT_LINE('Broj primeraka: '|| v_red_knjiga.broj_primeraka);
    END LOOP;
END

Након што је креирана и сачувана, процедуру можемо да позовемо у програму. У следећем програму се идентификациони број издавача уноси са тастатуре, приказују се подаци о том издавачу, а затим се позива креирана процедура.

DECLARE
    v_id_izdavaca izdavaci.id%TYPE;
    v_izdavac izdavaci%ROWTYPE;
BEGIN
    v_id_izdavaca := :ID_IZDAVACA;
    SELECT * INTO v_izdavac FROM izdavaci
    WHERE id = v_id_izdavaca;
    DBMS_OUTPUT.PUT_LINE('Naziv izdavaca: '||v_izdavac.naziv);
    DBMS_OUTPUT.PUT_LINE('Adresa izdavaca: '||v_izdavac.adresa);
    DBMS_OUTPUT.PUT_LINE('Sajt izdavaca: '||v_izdavac.veb_sajt);
    spisak_knjiga(v_id_izdavaca);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Greska');
END
../_images/slika_92d.jpg ../_images/slika_92e.jpg

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

DECLARE
    CURSOR kursor_izdavaci IS SELECT * FROM izdavaci;
    v_izdavac izdavaci%ROWTYPE;
BEGIN
    FOR v_izdavac IN kursor_izdavaci LOOP
        DBMS_OUTPUT.PUT_LINE('Naziv izdavaca: '||v_izdavac.naziv);
        DBMS_OUTPUT.PUT_LINE('Adresa izdavaca: '||v_izdavac.adresa);
        DBMS_OUTPUT.PUT_LINE('Sajt izdavaca: '||v_izdavac.veb_sajt);
        spisak_knjiga(v_izdavac.id);
        DBMS_OUTPUT.PUT_LINE('---');
    END LOOP;
EXCEPTION
    WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Greska');
END
(Created using Swinx, RunestoneComponents and PetljaDoc)
© 2022 Petlja
A- A+