Objektové typy

Objektově orientované programování rapidně zvyšuje svoji popularitu, protože lze s její pomocí dosáhnout snížení ceny a množství času potřebných pro vytvoření komplexních aplikací. Objektově orientované programování v PL/SQL je založeno na objektových typech. S jejich pomocí lze vytvořit abstraktní reprezentaci objektů reálného světa. Jsou také vhodné jako "černé skříňky", které lze použít ve vlastních programech jenom se znalostí toho, co objekt dělá, ale není nutná znalost jak.

Úloha abstrakce

Abstrakce je zjednodušený popis nebo model nějaké entity reálného světa. Umožňují soustředit se na jádro problému a skrývají nepodstatné detaily. Například když řídíte auto, nepotřebujete vědět, jak pracuje motor. Jednoduché rozhraní, které se skládá z řadící páky, volantu, plynu a brzdy, umožňuje efektivní používání auta. Detaily o činnosti pod kapotou nejsou pro řízení důležité.

Abstrakce jsou hlavním prvkem programování. Například používáte procedurální abstrakci když skrýváte detaily složitého algoritmu pomocí procedury, které se posílají argumenty. Jedno volání procedury skryje detaily implementace. Pokud je třeba pozměnit implementaci, jednoduše změníte tělo procedury, přičemž hlavička zůstane stejná. Díky abstrakci není nutné měnit programy, které tuto proceduru volají.

Datovou abstrakci zase používáte, když zadáváte typ proměnné. Datový typ udává množinu hodnot a množinu operací nad těmito hodnotami. Například proměnná typu POSITIVE umožňuje uchovávat pouze kladná celá čísla a lze je sčítat, odčítat, násobit a podobně. Pro používání proměnných není nutné vědět, jak PL/SQL ukládá celá čísla nebo jak jsou implementovány aritmetické operace, jednoduše používáte programovací rozhranní.

Objektové typy jsou ve většině programovacích jazyků zobecněním vestavěných datových typů. PL/SQL nabízí množství zabudovaných skalárních a složených datových typů, nad kterými jsou definovány příslušné operace. Skalární typ (jako například CHAR) nemá žádné vnitřní komponenty. Složený typ (jako například RECORD) má komponenty, se kterými lze manipulovat odděleně. Podobně jako typ RECORD je i typ OBJECT složený typ. Ovšem jeho množinu operací definuje uživatel.

Momentálně nelze objektové typy definovat uvnitř PL/SQL bloku. Je třeba je vytvořit pomocí CREATE a uložit do databáze, kde je jednotlivé programy mohou sdílet. Program, který používá objektové typy budeme nazývat klientský program. Ten může deklarovat a manipulovat s objektem bez znalosti jeho vnitřní reprezentace dat nebo implementace jeho operací. To umožňuje psát program a objekty odděleně a měnit implementaci objektového typu bez modifikace programu. Takže objektové typy umožňují procedurální i datovou abstrakci.

Co je to objektový typ?

Objektový typ je uživatelem definovaný složený typ, který zapouzdřuje datové struktury spolu s funkcemi a procedurami, které jsou potřebné pro manipulaci s daty. Proměnné, které vytvářejí datové struktury nazýváme atributy. Funkce a procedury, které charakterizují chování objektu nazýváme metody.

Obvykle přemýšlíme o vlastnostech a chování objektu (jako například člověk, auto nebo bankovní účet). Například vlastnosti dítěte mohou být věk, váha a výška, chování pak třeba jí, pije, spí.

Po nadefinování objektového typu příkazem CREATE TYPE je vytvořena abstraktní podoba nějakého objektu reálného světa. Tato předloha specifikuje pouze ty vlastnosti a chování objektu, které budou používány uvnitř aplikace. Například zaměstnanec může mít mnoho vlastností, ale pro potřeby aplikace je jich nutná pouze malá část.

Předpokládejme, že potřebujete napsat program, který bude počítat zaměstnanecké prémie. Pro řešení problému nebudeme potřebovat všechny vlastnosti zaměstnance. Takže nadefinujeme abstraktního zaměstnance, který bude mít tyto vlastnosti (specifické pro tento problém): jméno, id, oddělení, funkce, plat a platovou třídu. Následně zjistíme, které operace budou potřeba pro práci s tímto abstraktním zaměstnancem. Například budeme potřebovat operaci, která umožní manažerovi změnit platovou třídu zaměstnance.

Dále nadefinujeme množinu proměnných (atributů) pro reprezentaci dat zaměstnance a množinu podprogramů (metod) pro implementaci operací. Nakonec sloučíme atributy a metody do objektového typu.

Datová struktura tvořená množinou atributů je veřejná (tj. viditelná klientským programům). Dobře napsané programy však nemanipulují s data přímo, ale místo toho používají množinu metod. Tímto způsobem zůstanou data konzistentní. (Momentální verze Oracle neumožňuje privátní datové struktury).

V době běhu, kdy jsou datové struktury naplněny hodnotami, vytváříte instance abstraktního zaměstnance. Lze vytvořit tolik instancí, kolik potřebujete. Každá instance má jméno, id, funkci atd. příslušného zaměstnance. Tato data mohou být čtena nebo měněna pouze metodami, které jsou na objektu definovány.

Proč používat objektové typy?

Objektové typy umožňují snížit složitost problému jeho rozložením na logické části. To vám umožňuje vytvářet softwarové komponenty, které jsou modulární, snadno udržovatelné a znovu použitelné. Umožňují také několika různým programátorským týmům pracovat souběžně na jednotlivých komponentách softwaru.

Pomocí zapouzdření operací spolu s daty vám objektové typy umožňují přesunout kód pro obsluhu dat mimo SQL skripty a PL/SQL bloky do metod objektů. Objektové typy minimalizují možnost chyby při manipulaci s daty tak, že se s daty operuje pouze pomocí příslušných operací. Dále také objektové typy skrývají implementační detaily, takže lze změnit implementaci bez vlivu na klientské programy.

Objektové typy umožňují realistické modelování dat. Složité entity reálného světa a vztahy mezi nimi mohou být přímo vytvářeny v objektových typech. Vaše programy nyní mohou lépe reflektovat svět, který se pokoušejí simulovat.

Sturuktura objektového typu

Podobně jako PACKAGE má objektový typ dvě části: specifikaci a tělo. Specifikací rozumíme rozhraní mezi objektem a aplikací, definujeme zde strukturu dat (atributů) objektu spolu s operacemi (metodami) s těmito daty pracujícími. Tělo pak plně definuje metody a tím implementuje specifikaci.

Veškeré informace potřebné pro klientské programy, aby mohly používat metody objektu, jsou uvedeny ve specifikaci. Specifikaci si lze představit jako operační rozhraní a tělo jako čenou skříňku. Lze ladit, vylepšovat nebo zaměnit tělo beze změn ve specifikaci a tedy bez ovlivnění klientských programů.

V specifikaci objektového typu musí být všechny atributy definovány před deklarací metod. Pouze metody jsou implementovány skrytě, takže pokud objekt neobsahuje žádné metody, není potřeba žádné tělo. Atributy nelze deklarovat v těle.

Veškeré deklarace ve specifikaci objektového typu jsou veřejné (viditelné mimo objekt). Tělo objektového typu však může obsahovat privátní deklarace, které definují metody potřebné pro interní manipulace s objektem. Rozsah privátních deklarací je lokální pro tělo objektového typu.

Části objektového typu

Objekt zapouzdřuje data a operace. Proto je možné v specifikaci objektu definovat atributy a metody, nikoliv však konstanty, vyjímky, kursory nebo typy. Je vyžadován alespoň jeden atribut (maximální počet atributů je 1000), počet metod je volitelný.

Atributy

Podobně jako proměnné i atributy jsou deklarovány svým jménem a datovým typem. Jméno atributu musí být v rámci objektu unikátní (jiné objekty však toto jméno mohou použít). Datový typ může být libovolný Oracle typ kromě LONG, LONG RAW, NCHAR, NCLOB, NVARCHAR2, MLSLABEL a ROWID, dále kromě typů specifických pro PL/SQL jako jsou BINARY_INTEGER, BOOLEAN, PLS_INTEGER, RECORD, REF CURSOR, %TYPE, a %ROWTYPE a typů definovaných v PL/SQL PACKAGE.

Atributy nelze v deklaraci inicializovat pomocí přiřazení nebo klauzule DEFAULT. Na atributu také nelze definovat NOT NULL omezení. Objekty však lze ukládat do databázových tabulek, ve kterých tato omezení definovat lze.

Druh datové struktury definované množinou atributů zavisí na entity reálného světa, která je objektem reprezentována. Například pro reprezentaci racionálního čísla, které má čitatel a jmenovatel, jsou potřeba pouze dvě proměnné typu INTEGER. Na druhou stranu pro reprezentaci studenta vysoké školy je třeba množství VARCHAR2 proměnných, do kterých se bude ukládat jméno, adresa, telefon, stav a podobně, plus VARRAY proměnné, ve kterých budeme držet přednášky a stupně.

Datová struktura může být velmi složitá. Například datový typ atributu může být jiný objektový typ (vnořený objektový typ). To umožňuje vytvořit složitější objektové typy z jednodušších. Některé objektové typy, jako jsou například fronty, seznamy a stromy, jsou dynamické, tj. mohou se při používání zvětšovat. Rekurzivně definované typy, které obsahují přímý nebo nepřímý odkaz na sebe sama, umožňují vytvářet velmi sofistikované datové modely.

Metody

Metody jsou jednoduše řečeno podprogramy deklarované ve specifikaci objektového typu pomocí klíčového slova MEMBER. Metoda nemůže mít stejné jméno jako objekt sám nebo jako některý z jeho atributů.

Podobně jako podprogramy uvnitř PACKAGE většina metod má dvě části: specifikaci a tělo. Specifikace se skládá ze jména metody, seznamu parametrů (může být i prázdný) a pro funkce z návratové hodnoty. Tělo je kód který provádí příslušnou operaci.

Pro každou metodu uvedenou ve specifikaci musí být uvedeno příslušné tělo metody v těle objektového typu. Kompilátor PL/SQL porovnává hlavičku metody ve specifikaci metodou token-by-token. Proto musí hlavičky přesně odpovídat.

Uvnitř těla objektového typu mohou metody používat atributy i metody objektu bez kvalifikátoru (není nutné uvádět před atributem nebo metodou jméno objektu s tečkou). To ukazuje následující příklad:

CREATE TYPE Stack AS OBJECT ( 
   top INTEGER,
   MEMBER FUNCTION full RETURN BOOLEAN,
   MEMBER PROCEDURE push (n IN INTEGER),
   ...
);

CREATE TYPE BODY Stack AS 
   ...
   MEMBER PROCEDURE push (n IN INTEGER) IS 
   BEGIN
      IF NOT full THEN 
         top := top + 1;
         ...
   END push;
END;

Parametr SELF

Všechny metody v objektovém typu přijímají jako první argument instanci tohoto typu. Jméno tohoto zabudovaného argumentu je SELF. Ať už je parametr SELF deklarován implicitně nebo explicitně, vždy je volán jako první parametr metody. Například metoda transform deklaruje SELF jako IN OUT parametr:

CREATE TYPE Complex AS OBJECT ( 
   MEMBER FUNCTION transform (SELF IN OUT Complex) ...

Pokud v členské funkci není parametr SELF definován, jeho mód je nastaven jako IN. V členských procedurách je však parametr SELF implicitně deklarován jako IN OUT. Datový typ parametru SELF musí být jméno tohoto objektového typu. nelze specifikovat jiný datový typ.

V těle metody parametr SELF ukazuje na instanci, jejíž metoda byla vyvolána. Metody mohou referencovat atributy objekty SELF bez kvalifikace (není nutné uvádět SELF.atribut). To ukazuje následující příklad:

CREATE FUNCTION gcd (x INTEGER, y INTEGER) RETURN INTEGER AS
-- find greatest common divisor of x and y
   ans INTEGER;
BEGIN
   IF (y <= x) AND (x MOD y = 0) THEN ans := y;
   ELSIF x < y THEN ans := gcd(y, x);
   ELSE ans := gcd(y, x MOD y);
   END IF;
   RETURN ans;
END;

CREATE TYPE Rational AS OBJECT ( 
   num INTEGER,
   den INTEGER,
   MEMBER PROCEDURE normalize,
   ...
);

CREATE TYPE BODY Rational AS 
   MEMBER PROCEDURE normalize IS
      g INTEGER;
   BEGIN
      --  the next two statements are equivalent
      g := gcd(SELF.num, SELF.den);
      g := gcd(num, den);
      num := num / g;
      den := den / g;
   END normalize;
   ...
END;

Přetěžování

Podobně jako podprogramy v PACKAGE lze i metody stejného druhu přetěžovat. To znamená, že lze použít stejné jméno pro různé metody, pokud se jejich formální parametry liší v počtu, pořadí nebo datovém typu. Když je pak některá z těchto metod volána, PL/SQL vybere správnou pomocí porovnání aktuálních a formálních parametrů.

Nelze přetížit dvě metody, pokud se jejich formální parametry liší pouze v módu parametru. Nelze také přetížit dvě funkce, které se liší pouze v návratovém typu.

Metody pro třídění

Hodnoty skalárních typů, jako jsou CHAR nebo REAL mají předdefinované uspořádání, které umožňuje jejich porovnávání. Instance objektových typů však implicitně žádné uspořádání definováno nemají. Pro uspořádání objektů PL/SQL používá mapovací metodu, napsanou programátorem. Mapování funguje tak, že se hodnota interních datových struktur objektu převede na hodnotu některého ze skalárních typů. V následujícím příkladu klíčové slovo MAP indikuje, že metoda convert třídí obejkty Rational pomocí realných hodnot:

CREATE TYPE Rational AS OBJECT ( 
   num INTEGER,
   den INTEGER,
   MAP MEMBER FUNCTION convert RETURN REAL,
   ...
);

CREATE TYPE BODY Rational AS 
   MAP MEMBER FUNCTION convert RETURN REAL IS
   -- convert rational number to real number
   BEGIN
      RETURN num / den;
   END convert;
   ...
END;

PL/SQL pak používá toto uspořádání pro vyhodnocování booleovských výrazů jako například x > y, aby mohlo provádět třídění pro klauzule DISTINCT, GROUP BY a ORDER BY.

Objektový typ může obsahovat pouze jednu mapovací metodu, což musí být funkce bez parametrů s návratovou hodnotou typu DATE, NUMBER, VARCHAR2 případně některý z ANSI SQL typu jako jsou CHARACTER nebo REAL.

Alternativně lze vložit PL/SQL kód s třídící metodou. Tato metoda má právě dvaparametry - zabudovaný parametr SELF a druhý parametr stejného typu. Porovnávací metoda vrátí záporné, nulu nebo kladné číslo, pokud je SELF menší než, rovno nebo větší než druhý parametr.

Každý objektový typ smí obsahovat nejvýše jednu třídící metodu, která musí být funkce vracející číselný typ. Příklad třídící metody:

CREATE TYPE Customer AS OBJECT (  
   id   NUMBER, 
   name VARCHAR2(20), 
   addr VARCHAR2(30), 
   ORDER MEMBER FUNCTION match (c Customer) RETURN INTEGER
); 

CREATE TYPE BODY Customer AS 
   ORDER MEMBER FUNCTION match (c Customer) RETURN INTEGER IS 
   BEGIN 
      IF id < c.id THEN 
         RETURN -1;  -- any negative number will do
      ELSIF id > c.id THEN 
         RETURN 1;   -- any positive number will do
      ELSE 
         RETURN 0; 
      END IF; 
   END;
END;

V objektovém typu smí být definována buď mapovací metoda nebo třídící metoda, ale ne obě zároveň. Pokud není zadána ani jedna z nich, lze objekty porovnávat pouze na shodu (objekty jsou rovny, pokud hodnoty korespondujících atributů jsou shodné).

Pokud potřebujete třídit nebo slučovat velké množství objektů, použijte mapovací metodu. Jedno volání nejprve namapuje veškeré objekty do skalárního typu a pak se třídí skaláry. Třídící metoda je méně efektivní, protože se musí volat opakovaně (dokáže najednou porovnat pouze dva objekty).

Konstruktory

Každý objektový typ má svůj konstruktor, což je systémem definovaná funkce se stejným jménem, jako je jméno objektového typu. Konstruktor lze použít pro inicializaci objektu a vrácení instance objektového typu.

Oracle vygeneruje konstruktor pro každý objektový typ. Formální parametry konstruktoru odpovídají jednotlivým atributům objektového typu. To znamená, že parametry jsou definovány ve stejném pořadí a se stejným jménem a typem jako atributy.

PL/SQL nikdy nevolá konstruktor implicitně, proto je třeba jej volat explicitně. Volání konstruktoru jsou povolena tam, kde je povoleno volat funkci.

Deklarace a inicializace objektů

Jakmile je jednou objektový typ definován a instalován ve schématu, je možné jej použít k deklaraci objektu v libovolném PL/SQL bloku, podprogramu nebo PACKAGE. Například lze použít objektový typ jako datový typ atributu, sloupce, proměnné, položku typu záznam, formálního parametru nebo návratové hodnoty funkce. Za běhu programu jsou vytvářeny instance objektového typu. Každý objekt může obsahovat jiné hodnoty atributů.

Tyto objekty mají stejná rozsahová a vytvářecí pravidla jako ostatní typy. V bloku nebo v podprogramu jsou lokální objekty vytvářeny při vstupu do bloku nebo podprogramu a jsou smazány při jeho opuštění. V PACKAGE jsou objekty vytvořeny v okamžiku prvního referencování tohoto PACKAGE a smazány na konci databázové session.

Deklarace objektů

Objektový typ lze použít všude tam, kde je možné použít zabudované typy jako jsou CHAR nebo NUMBER. Objekty lze také deklarovat jako formální parametry funkcí a procedur. Tímto způsobem lze přenášet objekty mezi podprogramy.

Inicializace objektů

Dokud není objekt nainicializován zavoláním příslušného konstruktoru, je objekt atomicky NULL. To znamená, že NULL je přímo objekt, nikoliv jeho atributy.

DECLARE
   r Rational;  -- r becomes atomically null
BEGIN
   r := Rational(2,3);  -- r becomes 2/3

Objekt, který je NULL, není nikdy roven jinému objektu. Ve skutečnosti výsledkem porovnání NULL objektu s jiným objektem je NULL. Pokud přiřadíte atomicky NULL objekt jinému objektu, i tento se stane atomicky NULL (a musí být znova inicializován).

DECLARE
   r Rational;
BEGIN
   r Rational := Rational(1,2);  -- r becomes 1/2
   r := NULL;  -- r becomes atomically null
   IF r IS NULL THEN ...  -- condition yields TRUE

Objekty lze také inicializovat přímo při jejich deklaraci:

DECLARE
   r Rational := Rational(2,3);  -- r becomes 2/3

Přistupování k atributům

K atributům objektu lze přistupovat pouze pomocí jejich jmen (nelze použít jejich pozici uvnitř objektového typu). Pro čtení nebo modifikaci atributů se používá tečková notace.

DECLARE
   r Rational := Rational(NULL, NULL);
   numerator   INTEGER;
   denominator INTEGER;
BEGIN
   ...
   denominator := r.den;
   r.num := numerator;

Volání konstruktorů a metod

Volání konstruktoru je povoleno v místech, kde je povoleno volat funkci. Podobně jako ostatní funkce je i konstruktor volán jako část výrazu.

DECLARE
   r1 Rational := Rational(2, 3);
   FUNCTION average (x Rational, y Rational) RETURN Rational IS
   BEGIN 
      ... 
   END;
BEGIN
   r1 := average(Rational(3, 4), Rational(7, 11)); 
   IF (Rational(5, 8) > r1) THEN 
      ...
   END IF;
END;

Posílání parametrů konstruktoru

Parametry, které posíláte konstruktoru, nastavují iniciální hodnoty jednotlivým atributům objektu, který je inicializován. Je třeba zadat jeden parametr pro každý z atributů, protože narozdíl od konstant a proměnných atributy nemohou mít klauzuli DEFAULT.

DECLARE
   r Rational;
BEGIN
   r := Rational(5, 6);  -- assign 5 to num, 6 to den
   -- now r is 5/6

Ve volání konstruktoru lze použít i "named" notaci, namísto poziční notace.

BEGIN
   r := Rational(den => 6, num => 5);  -- assign 5 to num, 6 to den

Volání metod

Podobně jako podprogramy v PACKAGE i metody jsou volány za použití tečkové notace. Pokud je návratovou hodnotou z metody (funkce) objekt, lze na něm přímo zavolat další metodu (tj. volání se chová, jako by tam byl jiný objekt). Takováto volání nazýváme řetězení volání.

DECLARE
   r Rational := Rational(6, 8);
BEGIN
   r.reciprocal().normalize;
   DBMS_OUTPUT.PUT_LINE(r.num);  -- prints 4 

V SQL příkazech je vyžadován při volání metody bez parametrů prázdný seznam parametrů. V procedurálních příkazech není prázdný seznam parametrů vyžadován až na případy, kdy se řetězí volání, kde je nutné prázdný seznam parametrů uvádět všude až na poslední metodu.

Sdílení objektů

Většina objektů reálného světa má poměrně velkou a složitou strukturu s různými vazbami na jiné objekty. Pokud je objekt velký, je neefektivní při každém volání podprogramu s objektem jako parametr tento objekt kopírovat. Daleko jednodušší by bylo objekt sdílet. Toho lze v Oracle dosáhnout pomocí referencí. Reference je ukazatel na objekt.

Sdílení objektů má dvě hlavní výhody. První je, že nejsou zbytečně kopírována data. Druhou výhodou je, že pokud je sdílený objekt pozměněn, změna se provede pouze v jednom místě a jakákoliv reference může přímo pracovat s aktuálními daty.

CREATE TYPE Person AS OBJECT ( 
   first_name   VARCHAR2(10),
   last_name    VARCHAR2(15),
   birthday     DATE,
   home_address REF Home,  -- can be shared by family
   phone_number VARCHAR2(15),
   ss_number    INTEGER,
   mother       REF Person, -- family members refer to each other
   father       REF Person, 
   ...
);

Forward deklarace

V PL/SQL se lze odkazovat pouze na schéma, které již existuje. Můžeme však použít tzv. forward deklaraci, která nám umožní použít objekt, který ještě není deklarován (neúplná deklarace).

Switching the CREATE TYPE statements does not help because the object types are mutually dependent; that is, one depends on the other through a ref. To solve this problem, you use a special CREATE TYPE statement called a forward type definition, which lets you define mutually dependent object types.

To debug the last example, simply precede it with the following statement:

CREATE TYPE Department;  -- forward type definition
   -- at this point, Department is an incomplete object type

CREATE TYPE Employee AS OBJECT (
   name VARCHAR2(20),
   dept REF Department,  -- illegal
   ...
);

CREATE TYPE Department AS OBJECT (
   number  INTEGER,
   manager Employee,
   ...
);

Manipulace s objekty

You can use an object type in the CREATE TABLE statement to specify the datatype of a column. Once the table is created, you can use SQL statements to insert an object, select its attributes, call its methods, and update its state.

V příkazu CREATE TABLE lze použít objektový typ ve specifikaci datového typu sloupce. Jakmile je tabulka vytvořena, je možné použít SQL příkazy pro vkládání objektů, vypisování atributů uložených objektů, volání jejich metod a aktualizace jejich stavu.

CREATE TABLE numbers (rn Rational, ...)
/
INSERT INTO numbers (rn) VALUES (Rational(3, 62))  -- inserts 3/62
/
SELECT n.rn.num INTO my_num FROM numbers n WHERE ...  -- returns 3
/
UPDATE numbers n SET n.rn = n.rn.reciprocal WHERE ...  -- yields 62/3
/

Pokud tímto způsobem vytvoříte instanci objektu, tato instance nemá žádnou identitu mimo tabulku, ve které byla vytvořen. Objektový typ však existuje nezávisle na jakékoliv tabulce a může být využit pro vytváření instancí jinými způsoby.

Lze také vytvořit tabulku, jejíž řádky budou přímo objekty (tj. do jedné tabulky ukládáme instance jednoho objektového typu). Jednotlivé sloupce tabulky pak korespondují jednomu atributu objektového typu. Těmto tabulkám říkáme objektové tabulky.

CREATE TABLE rational_nums OF Rational;

Výběr objektů (SELECT)

Předpokládejme, že byl spuštěn tento SQL*Plus skript, který vytvoří objektový typ Person a objektovou tabulku nad tímto typem:

CREATE TYPE Person AS OBJECT ( 
   first_name   VARCHAR2(15),
   last_name    VARCHAR2(15),
   birthday     DATE,
   home_address Address,
   phone_number VARCHAR2(15))
/
CREATE TABLE persons OF Person
/

Následující dotaz vybere všechny objekty, jejichž atribut last_name končí Smith a vloží je do jiné objektové tabulky.

BEGIN
   INSERT INTO employees  -- another object table of type Person
      SELECT * FROM persons p
          WHERE p.last_name LIKE `%Smith';

Použití operátoru VALUE

Pomocí operátoru VALUE lze z objektové tabulky vybrat celý objekt a jeho hodnotu přiřadit například do jiné proměnné objektového typu. Jejím argumentem je korelační proměnná (což je jméno objektové tabulky, případně jejího aliasu)

BEGIN
   INSERT INTO employees
      SELECT VALUE(p) FROM persons p 
          WHERE p.last_name LIKE `%Smith';

DECLARE
   p1 Person;
   p2 Person;
   ...
BEGIN
   SELECT VALUE(p) INTO p1 FROM persons p 
      WHERE p.last_name = `Kroll';
   p2 := p1;
   ...
END;

Použití operátoru REF

Pomocí operátoru REF lze vytvářet odkazy na objekt v tabulce. Podobně jako operátor VALUE je jeho argumentem korelační proměnná.

BEGIN
   INSERT INTO person_refs
      SELECT REF(p) FROM persons p 
          WHERE p.last_name LIKE '%Smith';

DECLARE
   p_ref       REF Person;
   taxpayer_id VARCHAR2(9);
BEGIN
   SELECT REF(p), p.ss_number INTO p_ref, taxpayer_id 
      FROM persons p
      WHERE p.last_name = 'Parker'; -- must return one row
   ...
END;

Pokud je objekt, na který ukazuje reference, smazán, reference se stává takzvaně visící (ukazuje na neexistující objekt). Toto lze testovat pomocí predikátu IS DANGLING.

BEGIN
   UPDATE department SET manager = NULL WHERE manager IS DANGLING;

Použití operátoru DEREF

Uvnitř PL/SQL bloků nelze používat instance, na které máme pouze referenci. Je proto nutné použít operátor DEREF, aby bylo možné s instancí pracovat. DEREF dostane jako argument referenci na objekt a vrátí hodnotu objektu. Pokud je reference visící, pak vrátí NULL.

DECLARE
   p1    Person;
   p_ref REF Person;
   name  VARCHAR2(15);
BEGIN
   ...
   /* Assume that p_ref holds a valid reference
      to an object stored in an object table. */
   SELECT DEREF(p_ref) INTO p1 FROM dual;
   name := p1.last_name;

Operátor DEREF však nelze použít v procedurální části PL/SQL kódu:

BEGIN
   ...
   p1 := DEREF(p_ref);  -- illegal

Uvnitř SQL příkazu lze použít tečkovou notaci, pro procházení referencí, to však v procedurální části možné není (tam je nutné použít operátor DEREF).

Vkládání objektů

Pro vkládání objektů do objektové tabulky je třeba použít příkaz INSERT. Jako položky VALUES části píšeme přímo atributy objektu.

BEGIN
   INSERT INTO persons 
      VALUES ('Jenifer', 'Lapidus', ...);

Alternativně lze také do VALUES části uvést konstruktor objektu.

BEGIN
   INSERT INTO persons 
      VALUES (Person('Albert', 'Brooker', ...));

Modifikace existujících objektů

Pro modifikace existujících objektů v objektové tabulce je třeba použít příkaz UPDATE.

BEGIN
   UPDATE persons p SET p.home_address = '341 Oakdene Ave' 
      WHERE p.last_name = 'Brody';
   ...
   UPDATE persons p SET p = Person('Beth', 'Steinberg', ...)
      WHERE p.last_name = 'Steinway';
   ...
END;

Výmaz objektů

Příkazem DELETE lze smazat objekty z objektové tabulky. Pro selektivní výmaz objektů lze použít klauzuli WHERE.

BEGIN
   DELETE FROM persons p
      WHERE p.home_address = '108 Palm Dr';
   ...
END;