Jazyk PL/SQL
1) Jazyk PL/SQL

PL/SQL je proceduralni jazyk (cykly, podminky, funkce, procedury).
Zakladem je blok (nepojmenovany - anonymni, funkce, procedura).
Bloky mohou byt vnorene. Struktura bloku:


[DECLARE -- declarations] 
BEGIN -- statements 
[EXCEPTION
 -- handlers]
END;

Cast deklarace promennych a osetreni vyjimek je nepovinna.

2) Cast deklarace
Promenne a konstanty musi byt deklarovany drive, nez jsou pouzity.
Promenne a konstanty mohou mit libovolny SQL nebo PL/SQL datovy typ.

Napr. 
jmeno VARCHAR2(20); ucitel BOOLEAN;

Konstanty maji uvedeno klicove slovo CONSTANT a okamzite prirazenu
hodnotu:
pi CONSTANT real := 3.1415;

Promenna muze byt naplnena 3 zpusoby:
a) prirazovaci prikaz

cena := pocet_hodin * sazba; ucitel := TRUE;

b) klausule INTO prikazu select

SELECT 1+1 INTO cena FROM dual; 
SELECT uco INTO cislo_osoby FROM lide WHERE rc=8254074667;

c) vystupnim parametrem (OUT nebo IN OUT) procedury

zvys_plat(plat,100);


Atributy (pro zadavani datovych typu)

Mame tabulku kniha a ta ma atribut nazev. Aniz bychom znali (nebo
chteli presne specifikovat) datovy typ tohoto atributu, muzeme
vytvorit promennou
se stejnym datovym typem pomoci %TYPE.

nazev_knihy kniha.nazev%TYPE

Obdobne muzeme vytvorit promennou typu zaznam se vsemi atributy
urcite tabulky
(budeme do mi moci vlozit prave jeden radek tabulky). Slouzi k tomu %ROWTYPE.
(funguje to i na kursory, ale o tom az priste).

Napr.: Mejme tabulku lide s atributy jmeno, uco, rc:

clovek lide%ROWTYPE

Jednotlive polozky pak zpristupnime pomoci "."

INSERT INTO seznam VALUES (clovek.uco);

3) Cast prikazu
a) podminky IF-THEN-ELSE

IF kredit >= 80 THEN
 insert into log values('Pripojeni GPRS povoleno',SYSDATE);
 povolit := TRUE;
ELSE
 insert into log values('Prilis nizky kredit pro pripojeni GPRS',SYSDATE);
 povolit := FALSE;
END IF;

b) Nekonecny cyklus LOOP

i := 100; 
LOOP i:=i+2; 
  select salary into plat from employees where id=i; 
  celkem := celkem + plat; 
  EXIT WHEN j>1000; 
END LOOP;

c) Cyklus FOR-LOOP

FOR i IN 1..100 LOOP insert into mocniny values(i,i*i); END LOOP;

d) Cyklus WHILE-LOOP

WHILE salary <= 2500 LOOP select sal, mgr, ename into salary,
mgr_num, last_name
  from emp where empno = mgr_num;
END LOOP;

e) Nepodmineny skok GOTO

IF vykonnost > 90 THEN GOTO zvys_plat; END IF;
IF prac_napln = 'Prodejce' THEN plat := plat * 1.2; ELSE plat :=
plat * 1.1; END IF;


4) Funkce a procedury

[CREATE [OR REPLACE]] PROCEDURE jmeno_procedury (parametry) IS|AS
blok ... 
[CREATE [OR REPLACE]] FUNCTION jmeno_funkce (parametry)
RETURN datovy_typ IS|AS blok


kde parametry jsou tvaru: jmeno_parametru [IN|OUT [NOCOPY]|IN OUT
[NOCOPY]] datovy_typ [ {:=|DEFAULT} vyraz]

IN - vstupni parametr (default) OUT - vystupni parametr IN OUT -
vstupne/vystupni parametr

Defaultne se IN parametr predava referenci a OUT a IN OUT hodnotou.
Hint prekladace NOCOPY umozni i OUT a IN OUT parametry predavat
referenci.

DROP [PROCEDURE/FUNCTION] jmeno;


5) Vyjimky

Pri vyvolani vyjimky je preruseno provadeni programu a je spusteno osetreni
vyjimky. Existuje cela rada standardnich vyjimek (jako deleni nulou, chybejici
data, timeout), krome toho je mozne vytvaret a osetrovat uzivatelsky definovane
vyjimky.

EXCEPTION
WHEN vyjimky THEN 
...
WHEN VALUE_ERROR or ZERO_DIVIDE THEN
...
WHEN OTHERS THEN
...

Ne vsechny interni vyjimky jsou pojmenovane (jako napr. ZERO_DIVIDE), proto
je muzeme osetrovat v casti OTHERS nebo pojmenovat:

PRAGMA EXCEPTION_INIT(exception_name, Oracle_error_number);

Napr:

DECLARE
deadlock_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(deadlock_detected, -60);
BEGIN
...
EXCEPTION
WHEN deadlock_detected THEN
 ...
END;


Manualni spusteni vyjimky: prikaz RAISE vyjimka;
Manualni spusteni vyjimky a predani chybove zpravy (az 2048 znaku) aplikaci:
raise_application_error(error_number, message[, {TRUE | FALSE}]);

Pro ziskani chyb po vytvoreni procedury/funkce s chybami pouzijte
prikaz show errors.