PL/SQL v příkladech / Skalární datové typy
Datové typy v PL/SQL dělíme na tři základní kategorie, a to na skalární, kompozitní a referenční. Do skalárních můžeme uložit typicky jen jednu hodnotu, kompozitní pojmou pole hodnot, případně jde o složitější struktury jako rekord nebo objekt. Referenční datový typ slouží jako ukazatel.
Boolean a číslo
Předchozí díl kromě struktury a řízení kódu zjednodušeně představil dva základní datové typy – číslo a logický datový typ. Následující příklad ukazuje dvě, resp. tři metody přiřazení hodnoty do proměnné. Výchozí inicializaci v deklarativní části, přiřazení ve výkonové části a přiřazení pomocí SQL dotazu za použití klíčového slova INTO
.
DECLARE l_Bool BOOLEAN; -- logický datový typ, nelze použít v SQL l_Cislo NUMBER:=100; -- typ číslo BEGIN l_Cislo:=200; SELECT 300 INTO l_Cislo FROM dual -- pomocná systémová tabulka ; IF (l_Bool IS NULL) THEN -- výchozí hodnota proměnné je vždy NULL dbms_output.put_line(l_Cislo); -- 300 END IF; END;
Datový typ NUMBER
dokáže uchovat jak celočíselné hodnoty, tak i hodnoty s pohyblivou desetinnou čárkou. Přesnost (celkový počet cifer) a měřítko (počet cifer za desetinnou čárkou) můžeme specifikovat ručně. Pokud tak neučiníme, použije se maximální přesnost a měřítko. V PL/SQL můžeme pracovat také s různými číselnými pseudotypy, jako například INT
, který se interně mapuje na NUMBER(38,0)
. Kvůli co největšímu zjednodušení budu dále používat jen NUMBER
, více informací o číselných datových typech najdete v dokumentaci.
Znak a řetězec
Pro práci s řetězci předem stanovené délky slouží typ CHAR
, pro řetězce proměnné délky VARCHAR2
. Maximální velikost závisí na nastavení a zvolené znakové sadě a opět lze dohledat v dokumentaci. Obecně ale platí, že pro velmi dlouhý text je vhodnější použití datového typu CLOB
(„Character Large OBject“). Skládání řetězců a základní funkce pro práci s nimi popisuje následující příklad.
DECLARE l_Znak CHAR(1):='A'; -- pevně daná velikost l_Retezec VARCHAR2(4000):='slovo'; -- maximální velikost BEGIN -- skládání řetězců pomocí dvou pajp dbms_output.put_line(l_Retezec||' '||l_Znak); -- slovo A -- vyříznutí dbms_output.put_line(SUBSTR(l_Retezec, 1, 3)); -- slo -- pozice v řetězci dbms_output.put_line(INSTR(l_Retezec, 'ov')); -- 3 -- nahrazení dbms_output.put_line(REPLACE(l_Retezec, 'o', 'O')); -- slOvO END;
Datum
Pro uchování data používá Oracle typ DATE
, který obsahuje rok, měsíc, den, hodinu, minutu a vteřinu. Přiřazení probíhá pomocí funkce TO_DATE()
, konverze do lidsky čitelného řetězce funkcí TO_CHAR()
. Obě funkce přijímají jako druhý parametr formát.
DECLARE l_Datum DATE; l_Retezec VARCHAR2(20); BEGIN l_Datum:=TO_DATE('1.1.2016', 'DD.MM.YYYY'); -- přiřazení -- implicitní konverze dle nastavení databáze l_Retezec:=l_Datum; dbms_output.put_line(l_Retezec); -- 01.01.16 -- explicitní konverze pomocí formátu l_Retezec:=TO_CHAR(l_Datum, 'DD.MM.YYYY'); dbms_output.put_line(l_Retezec); -- 01.01.2016 -- načtení a konverze aktuálního data l_Retezec:=TO_CHAR(SYSDATE, 'HH24:MI:SS DD.MON.YY'); dbms_output.put_line(l_Retezec); -- 17:30:12 21.BŘE.16 -- načtení a konverze na název dne v týdnu l_Retezec:=TO_CHAR(SYSDATE, 'DAY'); dbms_output.put_line(l_Retezec); -- PONDĚLÍ -- přepsání jazykového nastaveni databáze l_Retezec:=TO_CHAR(SYSDATE, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH'); dbms_output.put_line(l_Retezec); -- MON END;
Základní práci s datem jako přičtení hodiny, dne nebo měsíce shrnuje následující příklad.
DECLARE l_Datum DATE:=TO_DATE('01.01.2016', 'DD.MM.YYYY'); BEGIN -- přičtení dne dbms_output.put_line(l_Datum+1); -- 02.01.16 -- přičtení hodiny dbms_output.put_line(TO_CHAR(l_Datum+1/24, 'HH24:MI')); -- 01:00 -- přičtení měcíce dbms_output.put_line(ADD_MONTHS(l_Datum, 1)); -- 01.02.16 -- odečtení roku dbms_output.put_line(ADD_MONTHS(l_Datum, -12)); -- 01.01.15 -- poslední den v měsíci dbms_output.put_line(LAST_DAY(l_Datum)); -- 31.01.16 -- zaokrouhlený rozdíl měsíců dbms_output.put_line(ROUND(MONTHS_BETWEEN(l_Datum+80, l_Datum))); -- 3 END;
%TYPE
V případě, že si nejsme datovým typem jisti nebo se bude v průběhu času měnit, můžeme zvolit deklaraci podle jiné proměnné nebo sloupce v tabulce.
DECLARE l_Cislo NUMBER; l_Employee_ID l_Cislo%TYPE; -- NUMBER l_FirstName employees.first_name%TYPE; -- VARCHAR2(20) BEGIN l_Employee_ID:=100; l_FirstName:='Steven'; dbms_output.put_line(l_Employee_ID||' '||l_FirstName); -- 100 Steven END;
Konstanta a klauzule NOT NULL
Jazyk PL/SQL podporuje také konstanty, které není možné v těle bloku přepsat jinou hodnotou. Velmi užitečná je také NOT NULL
klauzule kontrolující, zda-li je daná proměnná incializovaná.
DECLARE L_CISLO CONSTANT NUMBER:=100; -- konstanta l_Bool BOOLEAN NOT NULL:=FALSE; -- neNULLový typ BEGIN -- NELZE L_CISLO:=200; -- NELZE l_Bool:=NULL; IF (NOT l_Bool) THEN dbms_output.put_line(L_CISLO); -- 100 END IF; END;
Maximální velikost základních datových typů
Datový typ | Velikost v SQL | Velikost v PL/SQL |
---|---|---|
NUMBER |
± 999…(38 „devítek“) | ± 999…(38 „devítek“) |
CHAR |
2000 bajtů * | 32767 bajtů * |
VARCHAR2 |
4000 bajtů * | 32767 bajtů * |
CLOB |
8 TB až 128 TB ** | 128 TB |
* pozor na to, že různé znaky mají v UTF-8 různou velikost
** závisí na nastavení velikosti databázového bloku
Zdravím Matěji, ráda bych poděkovala za super stránky, krásně mi pomáhají zorientovat se v PL/SQL kódu a myslím, že jistě nebudu jediná, které pomůžou.
Pak bych jen upozornila na malinkou nepřesnost
Výsledek je, pokud se nemýlím, 3 a ne 2. Trochu mě to zmátlo, protože 2 by byl výsledek, pokud by se počítalo od nuly, ale jak je zřejmé z předchozí ukázky, tak první znak = 1.
Pokud se pletu, tak se omlouvám.
Přeji hezký den
Bára