ANSI/ISO normy SQL – objektové vlastnosti jazyka SQL99.

Vývoj standardů SQL:

Standard je rozdělen na tři úrovně: entry, intermediate a full. Někdy je také uváděn mezistupeň mezi entry a intermediate jako transitional. Úrovně slouží k tomu, aby mohlo být u implementací standardu (jednotlivých databází) uvedeno do jaké míry splňují daný standard. 

Změny možno klasifikovat jako:

Jen formální změny oproti SQL-86 

Podpora různých druhů spojení jako NATURAL JOIN, INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN 

Podpora nových datových typů DATE, TIME, TIMESTAMP and INTERVAL, including various datetime and interval features (excluding time zones) 

Podpora dlouhých identifikátorů (do 128 znaků) 

Podpora kurzorů a směru získávání dat příkazem FETCH 

Podpora definice a používání znakových sad 

Podpora dočasných tabulek 

Možnost výběru přesnosti u datových typů TIME a TIMESTAMP 

Možnost testování pravdivostních hodnot pomocí TRUE, FALSE or UNKNOWN 

Vnořené tabulky ve FROM 

Vylepšené udělování práv 

SQL:1999 (SQL3)  Jedná se o standard pro relačně-objektový dotazovací jazyk (na rozdíl od předchozích verzí, které byly pouze relační) 

Jedná se o standard pro relačně-objektový dotazovací jazyk (na rozdíl od předchozích verzí, které byly pouze relační) 

Procedurální rozšíření (Příkazy řízení běhu - LOOP, IF...) 

Objektové rozšíření 

The SQL:1999 standard introduced a number of object-relational database features into SQL, chiefly among them structured user-defined types, usually called just structured types. These can be defined either in plain SQL with CREATE TYPE but also in Java via SQL/JRT. SQL structured types allow single inheritance.

Existují i novější standardy 

SQL:2003 (Představeny XML-vázané funkce, window funkce, standardizované sekvence a sloupce s automaticky generovanými hodnotami) 

SQL:2006 (SQL může být použito ve spojení s XML - možnost importu a skladování XML dat v SQL databázi, manipulaci s nimi a publikace dat v XML formě. Možnost využití XQuery) 

SQL:2008 (ORDER BY mimo definici kurzoru, INSTEAD OF triggery, přidán TRUNCATE příkaz) 

Jednotlivé databázové servery ne vždy dodržují ANSI normu – obvykle pouze SQL-92 Entry 

Čím vice se při vývoji aplikace využijí rysy vyšší než SQL-92 Entry, tím je menší šance, že aplikace bude provozuschopná i na jiné databázi 

většina z těchto rozšíření lze najít v jiných otázkách, proto zde nebudou více rozepsána.

Objektová rozšíření SŘBD Oracle

V současné době směřuje trend ve vývoji databázových systémů směrem k objektovým SŘBD, neboť objektové SŘBD umožňují snadněji a přesněji modelovat většinu z různých tříd aplikací. Proto se výrobci relačních SŘBD snaží své produkty rozšířit o některé základní vlastnosti objektových SŘBD, čímž vznikají tzv. objektově-relační SŘBD. Zmíněný tred se promítá i do nového standardu SQL 3, jehož součástí jsou i abstraktní datové typy, persistentní programové moduly a vhnízděné tabulky. Jedním z objektově-relačních SŘBD je i systém Oracle (od verze 8i), na kterém si nyní ukážeme některá objektová rozšíření relačního SŘBD. 

Abstraktní datový typ lze nadefinovat příkazem CREATE TYPE. Tento uživatelem definovaný ADT lze pak použít všude, kde jsou používány standardní datové typy SQL. Následující příklad ukazuje definici typu t_adresa reprezentujícího adresu obyvatele. Ukázána je i definice tabulky, kde jedním z atributů je objekt typu t_adresa : 

Informace o struktuře tabulky lze opět získat příkazem DESC obyvatele. Strukturu objektu zobrazíme rovněž příkazem DESC t_adresa. 

Práce s objekty v SQL je, až na malé výjimky, víceméně intuitivní. Vkládání záznamů ukazuje spodní příklad. Instance objektu třídy t_adresa je vytvořena voláním implicitního konstruktoru : 

V případě, že chceme přistupovat k jednotlivým datovým prvkům objektu, musíme použít aliasy : 

Obdobně provedeme i aktualizaci objektu : 

Objekt lze zrušit takto : 

Pozn. : V tomto případě nelze již provést první příkaz UPDATE z předchozího příkladu, protože objekt již neexistuje. Druhý příkaz UPDATE naopak vytvoří instanci novou. 

Metody objektů

Samozřejmě, že objekty v SQL 3 mohou mít kromě datových prvků i metody. Následující ukázka slouží pro ilustraci definice objektu s několika metodami. Implementace metod je definována v příkazu CREATE TYPE BODY. 

Řádek v tabulce může být reprezentován i objektem. Tabulku pak nadefinujeme jednoduše takto : 

Pro zajímavost si zkuste zobrazit strukturu ADT t_osoba příkazem DESC t_osoba a také strukturu tabulky osoby příkazem DESC osoby. 

Nyní vložíme do tabulky několik záznamů a zkusíme zavolat metodu věk() : 

Volání metod uvnitř PL/SQL bloku je stejné jako u ostatních objektově-orientovaných jazyků : 

V praxi se často vyskytují případy, kdy je třeba uložit do jednoho atributu více hodnot. Typickým případem jsou alternativní čísla telefonu, na kterých je dosažitelná určitá osoba. Relační model dat nás nutí vytvořit novou entitu pro telefonní čísla, což se nám může oprávněně zdát poněkud nepřirozené. V takovýchto případech lze s výhodou použít pole proměnné délky - VARRAY. Pole VARRAY může obsahovat různý počet položek stejného datového typu (tzn. i objekty), který nesmí překročit definovanou velikost pole. Způsob použití polí je ukázán v následujícím příkladě : 

Způsob vkládání a výběru záznamů se nemění : 

K jednotlivým záznamům pole lze přistupovat tak, že pole "přetypujeme" na tabulku (un-nesting). Všimněte si, že následující dotazy implicitně provádí spojení bázové a vnořené tabulky reprezentované polem : 

Nevýhodou polí je, že z hlediska aktualizace se s nimi pracuje jako s atomickými hodnotami. Ve výše uvedeném příkladě tedy nelze jednoduše přidat, změnit nebo odstranit telefonní číslo. Aktualizaci lze provést nejvýše následujícím způsobem : 

V PL/SQL je práce s polem VARRAY velmi snadná. K jednotlivým položkám lze přistupovat přes index. Kromě toho každé pole obsahuje atribut count, jehož hodnota udává počet prvků pole : 

Vhnízděné (vnořené) tabulky

Vnořené tabulky mají oproti polím tu výhodu, že z hlediska aktualizace lze přistupovat k jednotlivým řádkům, jejichž počet není nijak omezen (teoreticky). Nevýhodou však je, že prvky (řádky) v tabulce nemají definované pořadí, jak tomu je u polí. Vnořenou tabulku vytvoříme tak, že nadefinujeme uživatelský datový typ podobně jako u polí : 

Definujeme-li tabulku, která obsahuje vnořenou tabulku, musíme definovat jméno tabulky, kde budou fyzicky uloženy záznamy z vnořených tabulek. V uvedeném příkladě to je tabulka NTAB_ZAMESTNANCI : 

Ve skutečnosti jsou vnořené tabulky řešeny "klasickým způsobem" - vazba mezi mateřskou a vnořenou tabulkou je realizována přes skrytý sloupec NESTED_TABLE_ID, jak ukazuje spodní obrázek : 

Přestože tabulka NTAB_ZAMESTNANCI je viditelná v katalogu (příkazem SELECT * FROM tab;), není přístupná pro příkazy DML. Zrušíme-li mateřskou tabulku KATEDRY, je automaticky zrušena i tabulka NTAB_ZAMESTNANCI. Vkládání záznamů je stejné jako u polí : 

Dotazy nad vnořenými tabulkami : 

Aktualizace vnořených tabulek : 

Vnořenou tabulku zrušíme takto : 

Opětovné vytvoření prázdné, nebo naplněné vnořené tabulky : 

V některých případech nechceme v atributu uchovávat celý objekt, ale pouze referenci (ukazatel, odkaz) na něj. Proto byl v SQL3 zaveden typ reference. Uvažme případ, že máme danou databázi pracovišť a předmětů (nábytek apod.) uložených na jednotlivých pracovištích. Vzhledem k centrální správě předmětů by bylo poněkud nevýhodné mít u každého pracoviště vnořenou tabulku předmětů. Navíc předměty mohou být rozděleny do několika kategorií a tedy i tabulek. Následující příklad ukazuje nastíněnou situaci, kdy předměty jsou ukládány v jediné tabulce a u každého předmětu je reference na pracoviště, na němž se nachází : 

Několik poznámek k referencím : každý objekt v SŘBD je jednoznačně identifikován pomocí OID - Object IDentifier. OID je jednoznačný v rámci celého SŘBD, v distribuovaných SŘBD v rámci celé sítě. Je-li určitý objekt zrušen, jeho OID již není nikdy použito pro jiný objekt. Typicky je OID generován na základě jednoznačného identifikátoru hostitelského uzlu (např. HW adresa síťového adaptéru uzlu), časové značky (aktuální čas na uzlu) a sekvenčního čísla. 

Pro ilustraci si vyzkoušejte vytvořit nový objekt a vypsat jeho OID (referenci) : 

Reference na objekty nelze považovat za referenční integritní omezení. Referenční IO omezují rozsah hodnot atributu (většinou cizího klíče), kdežto reference je chápána jako ukazatel na určitý objekt, který ovšem nemusí existovat (vzpomeňte si na ukazatele v C ;-). Nicméně u referencí lze specifikovat rozsah, a to ve smyslu množiny objektů ve specifikované tabulce : 

Referenci na určitý objekt vložíme do záznamu takto : 

V případě, že se budeme snažit vložit do sloupce PRACOVISTE v tabulce PREDMETY referenci na objekt z jiné tabulky než KANCELARE, databáze vkládání záznamu odmítne hláškou : 

Přístup k objektům přes reference (dereference) je velmi snadný : 

Příklad : evidence zaměstnanců a jejich pracovišť

Uvažme databázi nějakého ústavu, kde jsou centrálně evidování zaměstnanci, jednotlivá pracoviště jsou evidována zvlášť. Vazba mezi pracovníkem a jeho pracovištěm je realizována referencí u záznamu pracovníka na záznam jeho pracoviště. Celou situaci ilustruje obrázek : 

Z předchozích příkladů využijeme typ t_pracoviste a tabulku KANCELARE. Zbývající tabulky vytvoříme takto : 

Tabulky ještě naplníme daty : 

Seznam všech zaměstnanců včetně jejich příslušnosti k pracovišti na závěr vypíšeme jistě elegantním způsobem : 
