w sqlplus . w osobnej linji żeby do bufora lub / żeby wykonać
Instrukcje sterujące
IF warunek THEN
ciąg_instrukcji
END IF;
IF warunek THEN
ciąg_instrukcji
ELSE
ciąg_instrukcji
END IF; --else dla False i Null
IF warunek THEN
ciąg_instrukcji
ELSIF warunek THEN
ciąg_instrukcji
END IF;
LOOP
ciąg_instrukcji (w tym EXIT lub EXIT WHEN warunek)
END LOOP;
FOR zmienna IN wartość1 .. wartość2 LOOP
null;
END LOOP;
WHILE warunek LOOP
null;
END LOOP;
Instrukcja select
SELECT wyrażenie, wyrażenie, ...
INTO zmienna, zmienna, ...
FROM tabela, tabela, ...
[WHERE ...][GROUP BY ...][HAVING ...][FOR UPDATE ...];
Musi zwracać dokładnie jeden wiersz wyników, np.
SELECT ename
INTO nazwisko
FROM emp
WHERE empno = 1030;
Zmienne systemowe
W PL/SQL (ale nie w SQL) można korzystać ze zmiennych systemowych.
SQL%ROWCOUNT
- liczba wierszy przetworzonych przez ostatnią instrukcje SQL
SQL%FOUND
- True
jeżeli został przetworzony przynajmniej jeden wiersz
SQL%NOTFOUND
- przeciwnie
oraz tylko w sekcji EXCEPTION
SQLERRM
- tekstowa informacja o błędzie
SQLCODE
- kod błędu
Komunikacja z użytkownikiem
Jest dostęp do zmiennych aplikacji korzystającej z bloku PL/SQL :nazwa_zmiennej
.
Można też użyć zmienych podstawienia sqlplus &nazwa_zmiennej
.
Do wypisywania na ekran można stosować DBMS_OUTPUT.Put_Line(napis)
wcześniej ustawiając SET ServerOutput ON
.
przykład 1
przykład 2
Wyjątki
W PL/SQL standardowe wyjątki mają przyporządkowane nazwy.
dup_val_on_index
- ta sama wartość w indeksie jednoznacznym
no_data_found
- zapytanie nie zwróciło wartość i dla zmiennych z klauzuli INTO
too_many_rows
- zapytanie zwróciło więcej niż jeden wiersz dla zmiennych z klauzuli INTO
zero_divide
- dzielenie przez zero
time_out_on_resource
- zbyt długie oczekiwanie na zasoby
invalid cursor
- niepoprawna operacja na kursorze
login_denied
- niepoprawna nazwa użytkownika/hasło
invalid_number
- błąd przy konwersji na liczbę
storage_error
- zabrakło pamięci
cursor_already_open
- kursor już otwarty
program error
- błąd w interpreterze PL/SQL
Podstawowy przykład
przykład 1
Błędy występujace w sekcji DECLARE
lub EXCEPTION
są przekazywane na zewnątrz.
przykład 2
Do sprawdzenia która instrukcja spowodowaća błąd można używać podbloków z własną obsługą błędów
lub użyć licznika zwiększanego po wykonaniu każdej instrukcji.
Nowe wyjątki definiujemy w sekcji DECLARE
za pomocą: nazwa_wyjątku EXCEPTION
Wyjątek można zgłosić przy pomocy: RAISE nazwa_wyjątku
przykład 3
Jest też procedura zgłaszająca wyjątek (wolno używać numerów od -20999 do -20000)
przykład 4
Można obsługiwać błędy przechwytywane przez serwer bazy danych
przykład 5
Kursory
CURSOR nazwa_kursora IS instrukcja_SELECT; --(bez INTO)
OPEN nazwa_kursora;
FETCH nazwa_kursora INTO zmienna, ...;
EXIT WHEN nazwa_kursora%NOTFOUND;
CLOSE nazwa_kursora;
przykład 1
Istnieje składnia skrócona.
przykład 2
Kursory można sparametryzować.
przykład 3
kursor%FOUND
- czy z bazy sprowadzono kolejny wiersz
kursor%NOTFOUND
- przeciwnie, już nie ma
kursor%ROWCOUNT
- liczba sprowadzonych dotąd wierszy
kursor%ISOPEN
- czy kursor jest otwarty
przykład 4
Jak przy SELECT można też blokować wiersze.
przykład 5
Można definiować typy kursorowe do przekazywania jako parametry procedur i funkcji.
przykład 6
Zmienna kursorowa jest jak wskaźnik (więc przekazujemy stan kursora). Nie można używać w kursorowym FOR.
Rekordy i tabele
Są rekordy (bardziej rekordowe niż typ wierszowy)
przykład 1
W algorytmach i do komunikacji aplikacji (szczególnie WWW) z bazą służą tabele.
Mogą przechowywać nieograniczoną liczbę wierszy i są indeksowane (niekoniecznie kolejnymi) liczbami całkowitymi BINARY_INTEGER
.
przykład 2
tab.EXISTS(i)
- czy i-ty element jest określony
tab.COUNT
- liczba elementów w tabeli
tab.FIRST
- pierwszy element w tabeli
tab.LAST
- ostatni element w tabeli
tab.PRIOR(i)
- element poprzedzający i-ty
tab.NEXT(i)
- element następujący po i-tym
tab.DELETE
- usuń wszystkie elementy
tab.DELETE(i)
- usuń i-ty element
tab.DELETE(i,j)
- usuń elementy od i-tego do j-tego
przykład 3
Procedury i funkcje
CREATE [OR REPLACE]
PROCEDURE nazwa(lista_parametrow) {AS|IS}
blok PL/SQL bez słowa DECLARE (ale to co pomiedzy DECLARE i BEGIN moze byc)
Typy przekazywania parametrów: IN, OUT, IN OUT
(domyślny).
Nie podajemy rozmiaru, czyli np. tylko VARCHAR2
(nadal można tab.kol%TYPE
)
przykład 1
Błędy przy kompilacji można obejrzeć dzięki show errors
CALL nazwa(param)
- z SQL
EXECUTE nazwa(param)
- z sqlplus
nazwa(param)
- z kodu PL/SQL
CREATE [OR REPLACE]
FUNCTION nazwa(lista_parametrow)
RETURN typ_danych {IS|AS}
blok PL/SQL bez słowa DECLARE
(ale to co pomiedzy DECLARE
i BEGIN
moze byc)
blok musi zawierac: RETURN wartosc
;
przykład 2
SELECT nazwa(parma) FROM tab;
- z SQL
VARIABLE x INETGER; EXECUTE :x := nazwa(parma)
- z sqlplus
x := nazwa(parma)
- z kodu PL/SQL
Można podawać wartości domyślne parametrów po słowie kluczowym DEFAULT
.
Parametry w wartościami domyślnymi muszą był na końcu.
Jak kilka to wywołujemy: fun(par1,par2, nazwa_par4 => par4)
przykład 3
Funkcji można używać w instrukcjach SQL tak jak funkcji standardowych, ale nie mogą
modyfikować stanu bazy, ani nie mogą mieć parametrów wyjściowych. Nie powinny korzystać ze zmiennych
nielokalnych zadeklarowanych w pakietach, ani z notacji: nazwa_param => wartosc
.
przykład 4
Żeby zobaczyć informację o parametrach procedury lub funkcji piszemy: DESC[RIBE] nazwa
Można też skorzystać z perspektywy słownikowej user_source
przykład 5
Procedury i funkcje można przeciążać.
Pakiety
Pakiet składa się z części publicznej (specyfikacja) i prywatnej (implementacja). Każda sesja ma
swój egzemplaż pakietu, czyli zmienne zachowują swoje wartości na czas trwania sesji.
CREATE [OR REPLACE] PACKAGE nazwa_pakietu AS
definicje obiektów publicznych (dla procedur i funkcji tylko nagłówki)
END nazwa_pakietu;
CREATE [OR REPLACE] PACKAGE BODY nazwa_pakietu AS
definicje obiektów publicznych i prywatnych
[
BEGIN
instrukcje inicjalizujące
]
END nazwa_pakietu;
Nie można przekazywać kursora przez parametr procedury, ani współdzielić zmiennych kursorowych.
Definiując funkcje należy zamieszczać dyrektywę kompilatora: PRAGMA RESTRICT_REFERENCES(nazwa_funkcji, opcja, ...)
, gdzie:
WNDS
- funkcja nie modyfikuje bazy danych
WNPS
- funkcja nie modyfikuje zmiennych pakietu
RNDS
- funkcja nie odczytuje zawartości bazy danych
RNPS
- funkcja nie odczytuje zmiennych pakietu
Sekwencje
CREATE SEQUENCE nazwa_sekw
[INCREMENT BY k]
[START WITH n];
DROP SEQUENCE nazwa_sekw
Odwołujemy się przy pomocy nazwa_sekw.NextVal
oraz nazwa_sekw.CurrVal