BAZY DANYCH 2
Dr inż. Wikarek Jarosław
Katedra Systemów Sterowania i Zarządzania
E-MAIL: j.wikarek@tu.kielce.pl
1
JĘZYK PL/SQL
STRUKTURY KONTROLNE
Bazy danych
Instrukcje warunkowa
Instrukcja IF-THEN-ELSE
Podstawową instrukcją do konstruowania wyrażeń warunkowych
jest instrukcja IF o składni:
2
jest instrukcja IF o składni:
IF
wyrazenie_logiczne1
THEN
sekwencja_instrukcji;
[ELSIF
wyrazenie_logiczne2
THEN
sekwencja_instrukcji
;]
...
[ELSE
ostatnia_sekwencja_instrukcji
;]
END IF;
Bazy danych
Instrukcje warunkowa
Instrukcja IF-THEN-ELSE
3
Sekwencja instrukcji, jest wykonywana tylko wtedy, gdy związany
z nią warunek jest oceniany jako wartość TRUE. Jeżeli ten warunek
jest oceniany na wartość FALSE lub NULL, to sekwencja instrukcji
nie jest wykonywana.
Bazy danych
Insrukcje warunkowa
Przykład 1
DECLARE
z_Num1 NUMBER;
4
z_Num1 NUMBER;
z_Num2 NUMBER
z_Wynik VARCHAR(10);
BEGIN
IF z_Num1 < z_Num2 THEN
z_Wynik:=’Tak’;
ELSE
z_Wynik:=’Nie’;
END IF;
END;
Bazy danych
Instrukcje warunkowa
Przykład 2
Informacja o stanie magazynowym
DECLARE
5
DECLARE
z_StanProduktu
towary.stan%TYPE;
z_Komentarz
VARCHAR(50);
BEGIN
/* Pobranie stanu produktu nr_produktu=10. Zapamiętanie
wyniku w zmiennej z_StanProduktu. */
SELECT stan_produktu INTO z_StanProduktu FROM Towary
WHERE nr_produktu=10;
Bazy danych
Instrukcje warunkowa
Przykład 2
IF z_StanProduktu=0 THEN
6
IF z_StanProduktu=0 THEN
z_Komentarz:=’Zapas produktu wyczerpany’;
ELSIF z_StanProduktu<=1000 THEN
z_Komentarz:=’Zapas produktu na wyczerpaniu’;
ELSE
z_Komentarz:=’Zapas produktu nie wymaga uzupełnień’;
END IF;
END;
Bazy danych
Instrukcje warunkowa
Sprawdzająca instrukcja CASE
Składnia instrukcji sprawdzającej CASE jest następująca:
7
CASE zm_testowa
WHEN wart_1 THEN sekwencja_instrukcji1;
WHEN wart_2 THEN sekwencja_instrukcji2;
...
WHEN wart_n THEN sekwencja_instrukcjin;
[ELSE sekwencja_else;]
END CASE;
Bazy danych
Instrukcje warunkowa
Przykład
DECLARE
8
DECLARE
z_Kraj
kierowcy.kraj%TYPE;
z_Nalepka
VARCHAR(3);
BEGIN
-- Pobranie nazwy kraju dla określonego samochodu
SELECT kraj INTO z_kraj FROM kierowcy WHERE Nr_kierowcy = 1032;
Bazy danych
Instrukcje warunkowa
Przykład
CASE z_kraj
WHEN ‘Polska’
THEN z_Nalepka := ‘PL’;
9
WHEN ‘Polska’
THEN z_Nalepka := ‘PL’;
WHEN ‘Włochy’ THEN z_Nalepka := ‘I’;
WHEN ‘Holandia’ THEN z_Nalepka := ‘NL’;
WHEN ‘Austria’
THEN z_Nalepka := ‘A’;
WHEN ‘Szwecja’ THEN z_Nalepka := ‘S’;
ELSE
z_Nalepka:= ‘Nieznana’;
END CASE;
DBMS_OUTPUT.PUT_LINE(z_Nalepka);
END;
Bazy danych
Instrukcje warunkowa
Przykład 2
ORA-06592: Nie znaleziono wariantu CASE w
czasie wykonywania instrukcji CASE
DECLARE
10
DECLARE
z_Kwartal NUMBER:=0
BEGIN
CASE z_Kwartal
WHEN 1 THEN DBMS_OUTPUT.PUT_LINE(‘Kwartał 1’);
WHEN 2 THEN DBMS_OUTPUT.PUT_LINE(‘Kwartał 2’);
WHEN 3 THEN DBMS_OUTPUT.PUT_LINE(‘Kwartał 3’);
WHEN 4 THEN DBMS_OUTPUT.PUT_LINE(‘Kwartał 4’);
END CASE;
END;
Bazy danych
Instrukcje warunkowa
Wyszukująca instrukcja CASE
Wyszukująca instrukcja CASE ma następującą składnię:
CASE
11
CASE
WHEN
warunek_logiczny1
THEN
sekwencja_instrukcji1;
WHEN
warunek_logiczny2
THEN
sekwencja_instrukcji2;
...
WHEN
warunek_logicznyn
THEN
sekwencja_instrukcjin;
[ELSE
sekwencja_else
;]
END CASE;
Bazy danych
Instrukcje warunkowa
Przykład
DECLARE
z_Miesiac NUMBER:=4;
12
z_Miesiac NUMBER:=4;
z_StatusPracownik CHAR(3):=’Tak’;
BEGIN
CASE
WHEN z_Miesiac = 4 THEN DBMS_OUTPUT.PUT_LINE(‘Miesiąc
rozliczenia podatku!’);
WHEN z_Miesiac > 4 THEN DBMS_OUTPUT.PUT_LINE(‘Minął
termin rozliczenia podatku!’);
Bazy danych
Instrukcje warunkowa
Przykład
WHEN z_SatusPracownik =’Tak’ THEN
DBMS_OUTPUT.PUT_LINE(‘Pracownik
indywidualnie
rozlicza
13
DBMS_OUTPUT.PUT_LINE(‘Pracownik
indywidualnie
rozlicza
swój podatek.’);
DBMS_OUTPUT.PUT_LINE(‘Zakład
wystawia
pracownikowi
formularz podatkowy PIT 8B!’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘śaden
z
warunków
nie
jest
spełniony’);
END CASE;
END;
Bazy danych
Pętla LOOP
Prosta pętla wykonuje się w nieskończoność.
Wyjście z pętli jest możliwe tylko jako efekt wykonania polecenia
14
Wyjście z pętli jest możliwe tylko jako efekt wykonania polecenia
EXIT
EXIT WHEN.
W każdym przebiegu pętli wykonuje się sekwencja poleceń. Po ich
wykonaniu kontrola powraca do początku pętli.
Bazy danych
Pętla LOOP
LOOP
LOOP
sekwencja polecen;
sekwencja polecen;
15
sekwencja polecen;
sekwencja polecen;
IF warunek THEN
EXIT WHEN warunek;
EXIT;
END LOOP;
END IF;
END LOOP;
Bazy danych
Pętla LOOP – przykład 1
DECLARE
liczba NUMBER;
BEGIN
Wynik
1
2
3
4
5
6
7
8
16
BEGIN
liczba:=1;
Dbms_Output.put_line(‘Wynik);
LOOP
Dbms_Output.put_line(liczba);
EXIT WHEN liczba=10;
liczba:=liczba+1;
END LOOP;
END;
8
9
10
Bazy danych
Pętla LOOP – przykład 2
DECLARE
v_suma NUMBER := 0;
v_i INTEGER := 0;
c_koniec CONSTANT INTEGER :=10;
Wynik działania
Suma liczb od 0 do 10
55
17
c_koniec CONSTANT INTEGER :=10;
BEGIN
LOOP
v_suma := v_suma + v_i;
EXIT WHEN (v_i = c_koniec);
v_i := v_i + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Suma liczb
od 0 do ' || c_koniec);
DBMS_OUTPUT.PUT_LINE(v_suma);
END;
Bazy danych
Pętla LOOP – przykład 3
DECLARE
z_Licznik BINARY_INTEGER:=1;
BEGIN
18
BEGIN
LOOP
INSERT INTO tabela_tymcz VALUES
(z_Licznik, ‘Indeks pętli’);
z_Licznik:=z_Licznik + 1;
IF z_Licznik > 50 THEN
EXIT;
END IF;
END LOOP;
END;
Bazy danych
Pętla WHILE
Przed każda iteracja sprawdzany jest warunek.
Pętla jest wykonywano tak długo, jak długo warunek ma
19
Pętla jest wykonywano tak długo, jak długo warunek ma
wartość TRUE.
Jeżeli wartość warunku wynosi FALSE lub
UNKNOWN to
kontrola przechodzi do pierwszego polecenia po pętli.
Jeżeli warunek na samym początku nie był spełniony, to pętla
nie wykona się ani razu.
Bazy danych
Pętla WHILE
WHILE warunek LOOP
sekwencja poleceń;
20
sekwencja poleceń;
END LOOP;
UWAGA!!!
Należy pamiętać, aby w sekwencji operacji znalazło się
polecenie, które zmieni warunek, w przeciwnym przypadku
grozi pętlą nieskończoną.
Bazy danych
Pętla WHILE
DECLARE
liczba NUMBER;
BEGIN
Wynik
1
2
3
4
5
6
7
8
21
BEGIN
liczba:=1;
WHILE liczba<=10 LOOP
Dbms_Output.put_line(liczba);
liczba:=liczba+1;
END LOOP;
END;
8
9
10
Bazy danych
Pętla WHILE
DECLARE
a NUMBER := 10;
b NUMBER := 15;
BEGIN
Wynik działania
NWD=5
22
BEGIN
WHILE (a != b) LOOP
IF (a > b) THEN
a := a - b;
ELSE
b := b - a;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(' NWD = ' || a);
END;
Bazy danych
Pętla LOOP a WHILE
DECLARE
z_Licznik BINARY_INTEGER;
z_zm1 NUMBER;
z_zm2 NUMBER:=0;
DECLARE
z_Licznik BINARY_INTEGER;
z_zm1 NUMBER;
z_zm2 NUMBER:=0;
23
z_zm2 NUMBER:=0;
BEGIN
z_Licznik:=0;
LOOP
z_zm1:=z_zm2;
z_zm2:=z_zm1+1;
z_Licznik:=z_Licznik + 1;
EXIT WHEN z_Licznik = 100
OR z_zm2>99 ;
END LOOP;
END;
z_zm2 NUMBER:=0;
BEGIN
z_Licznik:=0;
z_zm1:=z_zm2;
z_zm2:=z_zm1+1;
WHILE z_Licznik = 100 OR
z_zm2<99 LOOP
z_zm1:=z_zm2;
z_zm2:=z_zm1+1;
z_Licznik:=z_Licznik + 1;
END LOOP;
END;
Bazy danych
Pętla FOR
Pętla FOR wykonuje się określoną liczbę razy.
Liczba iteracji jest
określona przez zakres podany miedzy
24
Liczba iteracji jest
określona przez zakres podany miedzy
słowami kluczowymi FOR i LOOP.
Zakres musi być typu numerycznego, w przedziale –2^31 , 2^31
Bazy danych
Pętla FOR
FOR licznik IN [ REVERSE ] dolna_gr .. górna_gr LOOP
sekwencja poleceń;
END LOOP;
25
END LOOP;
Gdzie
Słowo kluczowe REVERSE odwraca kierunek iteracji
Wewnątrz pętli nie wolno nadawać wartości zmiennej iterującej
Jeśli dolna granica jest wyższa niż górna granica to pętla nie wykona się
ani razu
Obie granice zakresu iteracji nie musza być statyczne
Zmienna iterująca nie musi być wcześniej deklarowana ani inicjalizowana
Do wcześniejszego wyjścia z pętli można użyć polecenia Exit
Bazy danych
Pętla FOR
BEGIN
FOR i IN 1..10 LOOP
Wynik działania
1 -
2 --
3 ---
4 ----
5 -----
6 ------
7 -------
26
FOR i IN 1..10 LOOP
Dbms_Output.put_line(i||’ ‘||lpad(‘-’,i,’-’));
END LOOP;
END;
7 -------
8 --------
9 ---------
10 ----------
Bazy danych
Pętla FOR
DECLARE
a NUMBER := 10; is_prime BOOLEAN;
BEGIN
FOR i IN 1 .. a LOOP
Wynik działania
1
jest liczba pierwsza
2
jest liczba pierwsza
3
jest liczba pierwsza
5
jest liczba pierwsza
7
jest liczba pierwsza
27
FOR i IN 1 .. a LOOP
is_prime := TRUE;
FOR j IN 2 .. i/2 LOOP
IF (MOD(i,j) = 0) THEN
is_prime := FALSE;
END IF;
END LOOP;
IF (is_prime) THEN
DBMS_OUTPUT.PUT_LINE(i || ' jest liczba pierwsza');
END IF;
END LOOP;
END;
Bazy danych
Pętla FOR
BEGIN
FOR i IN REVERSE 1..10 LOOP
Wynik działania
10
9
8
7
6
5
4
28
FOR i IN REVERSE 1..10 LOOP
Dbms_Output.put_line(i);
END LOOP;
END;
4
3
2
1
Bazy danych
Polecenia sterujące GOTO i NULL
Polecenie NULL nie wykonuje żadnej akcji.
Polecenie
GOTO
bezwarunkowo
przekazuje
kontrole
wykonywania programu do miejsca wskazywanego przez
etykietę związaną z poleceniem.
29
etykietę związaną z poleceniem.
Etykieta musi poprzedzać polecenie wykonywalne
GOTO nie może przeskakiwać do warunkowych części
poleceń
IF-THEN-ELSE,
CASE,
do polecenia LOOP
do bloku podrzędnego
GOTO nie może wyskakiwać z podprogramu oraz
procedury obsługi błędu
Bazy danych
Polecenia sterujące GOTO
GOTO etykieta;
...
30
...
<<etykieta>>
Bazy danych
Polecenia sterujące GOTO
DECLARE
v_tekst VARCHAR2(20);
BEGIN
<<poczatek>>
Wynik działania
Ala ma asa
31
<<poczatek>>
v_tekst := 'Ala '; GOTO ma;
<<asa>>
v_tekst := v_tekst || 'asa '; GOTO drukuj;
<<drukuj>>
DBMS_OUTPUT.PUT_LINE(v_tekst); GOTO koniec;
<<ma>>
v_tekst := v_tekst || 'ma '; GOTO asa;
<<koniec>>
NULL;
END;
Bazy danych
Polecenia sterujące GOTO
DECLARE
z_Licznik BINARY_INTEGER:=1;
BEGIN
32
BEGIN
LOOP
INSERT INTO tabela_tymcz VALUES (z_Licznik, ‘Licznik pętli’);
z_Licznik:= z_Licznik + 1;
IF z_Licznik > 10 THEN
GOTO e_KoniecPetli;
END IF;
END LOOP;
<<e_Koniec_Pętli>>
INSERT INTO tabela_tymcz(kol_znak) VALUES(‘Operacja wykonana!’);
END;
Bazy danych
KURSORY
33
Kursor (ang.
cursor
) jest uchwytem lub inaczej wskaźnikiem do obszaru
kontekstu. Można powiedzieć, iż w przypadku zapytania kursor jest wskaźnikiem
do takiego obszaru pamięci, który przechowuje zbiór wyników wielowierszowego
tego zapytania.
Bazy danych
Kursory
Aby w programach języka PL/SQL można było przetwarzać dane
przechowywane w bazie danych, należy je uprzednio pobrać do
34
przechowywane w bazie danych, należy je uprzednio pobrać do
programów.
Służą do tego kursory, które pozwalają programowi jawnie sterować
przetwarzaniem instrukcji SQL
Bazy danych
Kursory
Wyróżnia się dwa rodzaje kursorów:
kursory jawne (ang.
explicit cursors
)
Są takim rodzajem kursora, w którym
nazwa kursora jest
35
Są takim rodzajem kursora, w którym
nazwa kursora jest
jawnie przydzielona instrukcji SELECT za pomocą instrukcji
CURSOR...IS.
kursory niejawne (ang.
implicit cursors
)
Są takim rodzajem kursorów, które są
definiowane przez
system ORACLE i dotyczą instrukcji SELECT...INTO, INSERT,
UPDATE oraz DELETE. „Niejawność” tego typu kursora
wynika z braku bezpośrednich odwołań do niego w kodzie
PL/SQL.
Operacje
związane
z
kursorem
niejawnym
są
automatycznie wykonywane przez mechanizm PL/SQL.
Bazy danych
Kursory
Atrybuty kursorów
SQL%FOUND
Wskazuje, czy instrukcja INSERT, UPDATE lub DELETE miała
36
Wskazuje, czy instrukcja INSERT, UPDATE lub DELETE miała
wpływ na jakiś wiersz czy też nie.
SQL%NOTFOUND
Wskazuje, czy instrukcji INSERT, UPDATE lub DELETE nie udało
się zmodyfikować żadnego wiersza
SQL%ISOPEN
Wskazuje, czy kursor jest otwarty czy też nie.
SQL%ROWCOUNT
Wskazuje liczby wierszy zmodyfikowanych za pomocą którejś z
instrukcji INSERT, UPDATE lub DELETE.
Bazy danych
Kursory
Kursory niejawne
BEGIN
UPDATE klienci SET kraj = ‘Polska’ WHERE id = 1216;
37
UPDATE klienci SET kraj = ‘Polska’ WHERE id = 1216;
IF SQL%NOTFOUND THEN
INSERT INTO klienci (id, nazwa, kraj)
VALUES (1216, ‘Martex Sp. z o.o.’, ‘Polska’);
END IF;
END;
Jeżeli klient o id=1216 nie istnieje (nie został mu zatem
przypisany kraj ‘Polska’) należy wprowadzić go do tabeli klienci,
innymi słowy, gdy żaden wiersz z tabeli klienci nie spełnia
warunku id=1216, należy wprowadzić wiersz do tej tabeli
Bazy danych
Kursory
Kursory niejawne
BEGIN
DELETE FROM TABLE PRACOWNICY WHERE nazwisko like ‘K%’;
38
DELETE FROM TABLE PRACOWNICY WHERE nazwisko like ‘K%’;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE(‘Usunieto ‘||SQL%ROWCOUNT||’
rekordów’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Nie ma nikogo na K’);
END IF;
END;
Usuwa nazwiska zaczynające się na literę K i wyświetla ile rekordów
zostało usuniętych
Bazy danych
Kursory
Kursory jawne
Kursor jawny jest taką strukturą w kodzie programu PL/SQL, której
przetwarzanie wymaga wykonania następujących czynności:
39
przetwarzanie wymaga wykonania następujących czynności:
Zadeklarowanie kursora,
Otwarcie kursora dla zapytania,
Pobranie wyników do zmiennych PL/SQL,
Zamknięcie kursora.
Deklaracja kursora jest jedynym krokiem, który odbywa się w
sekcji deklaracji bloku; pozostałe trzy są wykonywane w sekcji
wykonania lub w sekcji wyjątków.
Bazy danych
Kursory
Kursory jawne
Zadeklarowanie kursora,
Deklarację kursora można potraktować jako sposób przypisania
40
Deklarację kursora można potraktować jako sposób przypisania
nazwy do instrukcji SELECT.
CURSOR
nazwa_kursora [par typ]
IS
instrukcja_SELECT
;
Bazy danych
Kursory
Kursory jawne
Zadeklarowanie kursora
DECLARE
41
DECLARE
CURSOR Kur_All_Prac IS SELECT * FROM Pracownicy;
CURSOR Kur_STAN IS SELECT nr_st nazwa FROM
Stanowiska where placa_min>2000;
CURSOR Kur_Place(id NUmber) IS SELECT * FROM Place
where nr_prac=id;
Rek_Kur1
Kur_All_Prac%ROWTYPE;
Rek_Kur2
Kur_STAN%ROWTYPE;
Rek_Kur3
Kur_Place%ROWTYPE;
Bazy danych
Kursory
Kursory jawne
Otwarcie kursora
OPEN
nazwa_kursora
42
OPEN
nazwa_kursora
Przykład
BEGIN
OPEN Kur_All_Prac;
OPEN Kur_STAN;
OPEN Kur_Place(2);
Jeśli z kursora korzystamy w pętli FOR nie trzeba go wcześniej otwierać
Bazy danych
Kursory
Pobieranie danych za pomocą kursora
Do pobierania wiersza danych służy instrukcja FETCH. Istnieją
następujące postacie instrukcji FETCH:
43
następujące postacie instrukcji FETCH:
FETCH
nazwa_kursora
INTO
lista_zmiennych;
FETCH
nazwa_kursora
INTO
rekord_PL/SQL;
FETCH
nazwa_kursora
INTO
table_name%ROWTYPE;
Bazy danych
Kursory
Pobieranie danych za pomocą kursora
Do pobierania wiersza danych służy instrukcja FETCH. Istnieją
następujące postacie instrukcji FETCH:
44
następujące postacie instrukcji FETCH:
FETCH Kur_All_Prac
INTO z_nr_p, z_imie, z_nazwisko ;
FETCH Kur_stan
INTO z_nazwa;
FETCH Kur_Place
INTO Rek_Kur3;
Bazy danych
Kursory
Pobieranie danych za pomocą kursora
Kolejna instrukcja FETCH nadpisuje wartości pochodzące z
poprzedniej.
45
poprzedniej.
Nie można pobrać wiersza, który został już uprzednio pobrany..
Po pobraniu wszystkich wierszy z aktywnego zbioru wierszy
wykonanie kolejnej instrukcji FETCH nie daje żadnego rezultatu
– nie spowoduje przypisania nowych danych do zmiennych, ale
także nie spowoduje przechwycenia żadnych wyjątków.
W celu wskazania momentu, w którym został pobrany już cały
zbiór wynikowy można wykorzystać tzw. atrybut kursora
%NOTFOUND
Bazy danych
Kursory
Zamykanie kursora
Wart pamiętać, iż po ukończeniu pobierania wszystkich wierszy z
aktywnego zbioru wierszy należy zamknąć kursor. Taka operacja
46
aktywnego zbioru wierszy należy zamknąć kursor. Taka operacja
informuje mechanizm PL/SQL, że przetwarzanie kursora zakończyło
się i zasoby z tym związane mogą być zwolnione. :
CLOSE
nazwa_kursora
Uwaga: Należy zawsze pamiętać o zamykaniu otwartych kursorów.
W przypadku, gdy liczba otwartych kursorów jest zbyt duża może
to skutkować zgłoszeniem błędu „
Zbyt duża liczba otwartych
kursorów
”.
Standardowo maksymalna liczba jednocześnie otwartych kursorów
wynosi 50.
Bazy danych
Kursory
Atrybuty kursora
%FOUND
Wskazuje, czy instrukcja FETCH pobrała wiersz danych z
aktywnego zbioru wierszy czy też nie.
47
aktywnego zbioru wierszy czy też nie.
%NOTFOUND
Wskazuje,
czy
instrukcja
FETCH
zakończyła
się
niepowodzeniem lub czy nie ma już żadnych wierszy do
pobrania z aktywnego zbioru wierszy.
%ISOPEN
Wskazuje, czy kursor jest otwarty czy też nie.
%ROWCOUNT
Wskazuje liczby wierszy pobranych za pomocą kursora do
danego momentu.
Bazy danych
Przykład 1 – pobranie danych
DECLARE
--Deklaracja kursora
CURSOR k_Dane IS SELECT * FROM tabela_tymcz
48
CURSOR k_Dane IS SELECT * FROM tabela_tymcz
z_RekordTymcz k_DaneTymcz%ROWTYPE;
BEGIN
OPEN k_Dane; --Otwarcie kursora
FETCH k_Dane INTO z_RekordTymcz; --Pobranie pierwszego wiersza
FETCH k_Dane INTO z_RekordTymcz; --Pobranie drugiego wiersza
FETCH k_Dane INTO z_RekordTymcz; --Pobranie trzeciego wiersza
CLOSE k_DaneTymcz;
END;
Bazy danych
Przykład 2 kursor i pętla
DECLARE
CURSOR k1 IS SELECT * FROM osoby ;
49
CURSOR k1 IS SELECT * FROM osoby ;
rek osoby%ROWTYPE;
BEGIN
OPEN k1;
FETCH k1 INTO rek;
CLOSE k1;
Dbms_Output.put_line(rek.imie);
END;
Bazy danych
Przykład 3 kursor i pętla
DECLARE
CURSOR k1 IS SELECT * FROM osoby ;
rek osoby%ROWTYPE;
50
BEGIN
OPEN k1;
LOOP
FETCH k1 INTO rek;
EXIT WHEN k1%NOTFOUND ;
Dbms_Output.put_line(rek.imie);
END LOOP;
CLOSE k1;
END;
Bazy danych
Przykład 3 kursor i pętla
DECLARE
CURSOR k1 IS SELECT * FROM osoby ;
rek osoby%ROWTYPE;
51
rek osoby%ROWTYPE;
BEGIN
FOR rek IN k1 LOOP
Dbms_Output.put_line(rPad(rek.imie,25,' ‘)||rek.nazwisko);
END LOOP;
END;
Bazy danych
Przykład 3 kursor i pętla
DECLARE
CURSOR k1 IS SELECT * FROM osoby ;
rek k1%ROWTYPE;
52
BEGIN
OPEN k1;
FETCH k1 INTO rek;
WHILE k1%FOUND LOOP
Dbms_Output.put_line(rek.imie);
FETCH k1 INTO rek;
END LOOP;
CLOSE k1;
END;
Bazy danych
Kursory
Klauzula WHERE CURRENT OF
Fraza WHERE CURRENT OF nazwa kursora identyfikuje kursor
wskazujący
na
wiersz,
który
ma
zostać
usunięty
lub
53
wskazujący
na
wiersz,
który
ma
zostać
usunięty
lub
zaktualizowany.
Bazy danych
Kursory
Klauzula WHERE CURRENT OF
DECLARE
CURSOR c IS SELECT * FROM pracownicy JOIN zespoly USING
(id_zesp) FOR UPDATE OF placa_pod;
54
(id_zesp) FOR UPDATE OF placa_pod;
BEGIN
FOR c_rec IN c LOOP
IF (c_rec.adres = 'PIOTROWO 3A') THEN
UPDATE pracownicy SET placa_pod = 1.1 * placa_pod
WHERE CURRENT OF c;
END IF;
END LOOP;
END;