Oracle Tipuri de obiecte PL/SQL: CREATE TYPE cu exemple
โก Rezumat inteligent
Tipurile de obiecte din PL/SQL aduc programarea orientatฤ pe obiecte la Oracle, permiศรขndu-vฤ sฤ modelaศi entitฤศi din lumea realฤ cu atribute ศi metode. Acestea acceptฤ constructori, moศtenire ศi comparare de egalitฤศi, astfel รฎncรขt un singur tip la nivel de schemฤ poate stoca ศi procesa date structurate.

Ce este tipul de obiect รฎn PL/SQL?
Programarea orientatฤ pe obiecte este potrivitฤ รฎn special pentru construirea de componente reutilizabile ศi aplicaศii complexe. Programele sunt organizate รฎn jurul โobiectelorโ mai degrabฤ decรขt al โacศiunilorโ; adicฤ, sunt concepute sฤ lucreze ศi sฤ interacศioneze cu un รฎntreg obiect, mai degrabฤ decรขt cu o singurฤ acศiune. Aceastฤ abordare permite programatorului sฤ populeze ศi sฤ manipuleze detalii la nivel de obiect-entitate.
Imaginea de mai jos prezintฤ un exemplu de tip de obiect รฎn care un cont bancar este tratat ca o entitate obiect. Atributele obiectului conศin valori - pentru un cont bancar acestea sunt numฤrul contului, soldul bancar ศi aศa mai departe - รฎn timp ce metodele obiectului descriu acศiuni precum calcularea ratei dobรขnzii sau generarea unui extras de cont, fiecare dintre acestea necesitรขnd un proces pentru a fi finalizatฤ.
In PL / SQLProgramarea orientatฤ pe obiecte se bazeazฤ pe tipuri de obiecte. Un tip de obiect poate reprezenta orice entitate din lumea realฤ. Secศiunile de mai jos exploreazฤ tipurile de obiecte, componentele acestora ศi modul de creare ศi utilizare a acestora.
Componentele tipurilor de obiecte
Un tip de obiect PL/SQL conศine รฎn principal douฤ componente.
- Atribute
- Membri/Metode
Atribute
Atributele sunt coloanele sau cรขmpurile รฎn care sunt stocate datele. Fiecare atribut este mapat la tipul de date care defineศte tipul de procesare ศi stocare pentru atributul respectiv. Un atribut poate avea orice valoare validฤ. Tip de date PL/SQL, sau poate fi de alt tip de obiect.
Membri/Metode
Membrii sau metodele sunt subprograme definite รฎn interiorul tipului de obiect. Nu sunt utilizate pentru stocarea datelor; รฎn schimb, definesc procesarea efectuatฤ รฎn interiorul tipului de obiect - de exemplu, validarea datelor รฎnainte de popularea obiectului. Sunt declarate รฎn specificaศia tipului de obiect ศi definite รฎn corpul tipului de obiect. Corpul este opศional: dacฤ nu sunt prezenศi membri, un tip de obiect nu are o parte a corpului.
Creaศi obiect รฎn Oracle
Un tip de obiect nu poate fi creat la nivel de subprogram; acesta poate fi creat doar la nivel de schemฤ. Odatฤ ce tipul de obiect este definit รฎn schemฤ, acesta poate fi utilizat รฎn subprograme. Tipul de obiect este creat folosind instrucศiunea โCREATE TYPEโ, iar corpul tipului poate fi creat numai dupฤ ce tipul sฤu de obiect existฤ.
Capturile de ecran de mai jos prezintฤ sintaxa CREATE TYPE pentru specificaศia obiectului ศi sintaxa CREATE TYPE BODY care defineศte metodele acestuia.
CREATE TYPE<object_type_name> AS OBJECT ( <attribute_l><datatype>, . . ); / CREATE TYPE BODY<object_type_name> AS OBJECT ( MEMBER[PROCEDURE|FUNCTION]<member_name> IS <declarative section> BEGIN <execution part> END; . . ); /
Explicaศia sintaxei:
- Sintaxa de mai sus aratฤ crearea unui OBJECT cu atribute ศi a unui OBJECT BODY cu metode.
- Metodele pot fi, de asemenea, supraรฎncฤrcate รฎn corpul obiectului.
Declaraศia de iniศializare a tipului de obiect
Ca ศi alte componente din PL/SQL, tipurile de obiecte trebuie declarate รฎnainte de a fi utilizate รฎntr-un program. Odatฤ ce tipul de obiect este creat, acesta poate fi utilizat รฎn secศiunea declarativฤ a unui subprogram pentru a declara o variabilฤ de tipul respectiv de obiect.
Ori de cรขte ori o variabilฤ este declaratฤ ca tip de obiect, la momentul execuศiei este creatฤ o nouฤ instanศฤ a tipului de obiect, iar aceastฤ instanศฤ nou creatฤ este referitฤ prin numele variabilei. รn acest fel, un singur tip de obiect poate stoca mai multe valori sub instanศe diferite.
Captura de ecran de mai jos aratฤ o variabilฤ declaratฤ ca un tip de obiect รฎn interiorul unui bloc PL/SQL.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
Explicaศia sintaxei:
- Sintaxa de mai sus prezintฤ declararea unui variabil ca tip de obiect รฎn secศiunea declarativฤ.
Odatฤ ce variabila este declaratฤ ca tip de obiect รฎntr-un subprogram, aceasta este atomic nulฤ โ รฎntregul obiect รฎn sine este nul. Trebuie iniศializatฤ cu valori รฎnainte de a putea fi utilizatฤ รฎn program. Obiectele sunt iniศializate folosind constructori.
Constructorii sunt metodele implicite ale unui obiect la care se poate face referire cu acelaศi nume ca ศi tipul obiectului. Captura de ecran de mai jos prezintฤ iniศializarea unei instanศe de tip obiect.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
Explicaศia sintaxei:
- Sintaxa de mai sus aratฤ iniศializarea instanศei de tip obiect cu o valoare nulฤ.
- Obiectul รฎn sine nu mai este nul odatฤ ce a fost iniศializat, dar atributele din interiorul obiectului rฤmรขn nule pรขnฤ cรขnd li se atribuie valori.
Constructori
Constructorii sunt metodele implicite ale unui obiect la care se poate face referire cu acelaศi nume ca ศi tipul obiectului. Ori de cรขte ori se face referire la obiect pentru prima datฤ, acest constructor este apelat implicit.
De asemenea, puteศi iniศializa obiecte folosind aceศti constructori. Un constructor poate fi definit explicit prin definirea unui membru รฎn corpul tipului de obiect cu acelaศi nume ca ศi tipul de obiect.
Exemplu 1: รn exemplul urmฤtor, folosim membrul de tip obiect pentru a insera รฎnregistrฤri รฎn tabelul emp cu valorile ('RRR', 1005, 20000, 1000) ศi ('PPP', 1006, 20000, 1001). Odatฤ ce datele sunt inserate, le afiศฤm folosind membrul de tip obiect. De asemenea, folosim un constructor explicit pentru a popula ID-ul managerului cu valoarea implicitฤ 1001 pentru a doua รฎnregistrare.
รl executฤm รฎn urmฤtorii paศi.
- Pasul 1: Creaศi tipul de obiect ศi corpul tipului de obiect.
- Pasul 2: Creaศi un bloc anonim pentru a apela tipul de obiect prin constructorul implicit pentru emp_no 1005.
- Pasul 3: Creaศi un bloc anonim pentru a apela tipul de obiect prin constructorul explicit pentru emp_no 1006.
Pasul 1) Creaศi tipul de obiect ศi corpul tipului de obiect.
Captura de ecran de mai jos prezintฤ specificaศia de tip de obiect emp_object creatฤ รฎmpreunฤ cu atributele ศi membrii sฤi.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records); /
Captura de ecran de mai jos aratฤ corpul de tip emp_object creat cu constructorul explicit ศi procedurile membre.
CREATE OR REPLACE TYPE BODY emp_object AS CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT IS BEGIN Dbms_output.put_line('Constructor fired..'); SELF.emp_no:=p_emp_no; SELF.emp_name:=p_emp_name; SELF.salary:=p_salary; SELF.manager:=1001; RETURN; END; MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; MEMBER PROCEDURE display_records IS BEGIN Dbms_output.put_line('Employee Name:'||emp_name); Dbms_output.put_line('Employee Number:'||emp_no); Dbms_output.put_line('Salary:'||salary); Dbms_output.put_line('Manager:'||manager); END; END; /
Code Explicaศie
- Code liniile 1-9: Crearea tipului de obiect โemp_objectโ cu 4 atribute ศi 3 membri. Acesta conศine definiศia unui constructor cu doar 3 parametri. (Constructorul implicit real conศine numฤrul de parametri egal cu numฤrul de atribute prezente รฎn tipul de obiect.)
- Code linia 10: Crearea corpului tipului.
- Code liniile 11-21: Definirea constructorului explicit. Atribuirea valorilor parametrilor atributelor ศi atribuirea valorii implicite โ1001โ atributului โmanagerโ.
- Code liniile 22-26: Definirea membrului โinsert_recordsโ, รฎn care valorile atributelor sunt inserate รฎn tabelul โempโ.
- Code liniile 27-34: Definirea membrului โdisplay_recordsโ, care afiศeazฤ valorile atributelor de tip obiect.
ieศire:
Tip creat
Tip body creat
Pas 2) Crearea unui bloc anonim pentru a apela tipul de obiect creat prin constructorul implicit pentru emp_no 1005.
Captura de ecran de mai jos prezintฤ blocul anonim care apeleazฤ emp_object prin constructorul implicit.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1005,'RRR',20000,1000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END;
Code Explicaศie
- Code liniile 37-45: Inserarea รฎnregistrฤrilor folosind constructorul implicit. Apelul cฤtre constructor conศine numฤrul real de valori ale atributelor.
- Code linia 38: Declarฤ โguru_emp_detโ ca fiind tipul de obiect โemp_objectโ.
- Code linia 41: Instrucศiunea โguru_emp_det.display_recordsโ apeleazฤ membrul โdisplay_recordsโ, iar valorile atributelor sunt afiศate.
- Code linia 42: Instrucศiunea โguru_emp_det.insert_recordsโ apeleazฤ membrul โinsert_recordsโ, iar valorile atributelor sunt inserate รฎn tabel. Blocul valideazฤ apoi tranzacศie.
ieศire:
Numele angajatului: RRR
Numฤr de angajat: 1005
Salariu: 20000
Manager: 1000
Pas 3) Crearea unui bloc anonim pentru a apela tipul de obiect creat prin constructorul explicit pentru emp_no 1006.
Captura de ecran de mai jos prezintฤ blocul anonim care apeleazฤ emp_object prin constructorul explicit cu trei argumente.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1006,'PPP',20000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END; /
producศie
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Code Explicaลฃie:
- Code liniile 46-53: Inserarea รฎnregistrฤrii folosind constructorul explicit.
- Code linia 46: Declarฤ โguru_emp_detโ ca fiind tipul de obiect โemp_objectโ.
- Code linia 50: Instrucศiunea โguru_emp_det.display_recordsโ apeleazฤ membrul โdisplay_recordsโ, iar valorile atributelor sunt afiศate.
- Code linia 51: Instrucศiunea โguru_emp_det.insert_recordsโ apeleazฤ membrul โinsert_recordsโ, iar valorile atributelor sunt inserate รฎn tabel. Deoarece sunt transmise doar trei argumente, constructorul explicit seteazฤ ID-ul managerului la valoarea implicitฤ 1001.
Moศtenirea รฎn tipul obiectului
Proprietatea de moศtenire permite unui tip de subobiect sฤ acceseze toate atributele ศi membrii tipului de superobiect sau ai tipului de obiect pฤrinte.
Tipul de sub-obiect se numeศte tipul de obiect moศtenit, iar tipul de super-obiect se numeศte tipul de obiect pฤrinte. Sintaxa de mai jos aratฤ cum se creeazฤ tipuri de obiecte pฤrinte ศi moศtenite. Captura de ecran de mai jos prezintฤ sintaxa tipului pฤrinte (SUPER) marcat ca NESFINAL.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
Explicaศia sintaxei:
- Sintaxa de mai sus ilustreazฤ crearea tipului SUPER. Clauza NOT FINAL permite moศtenirea tipului.
Captura de ecran de mai jos prezintฤ sintaxa de tip moศtenitฤ (SUB) creatฤ cu cuvรขntul cheie UNDER.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
Explicaศia sintaxei:
- Sintaxa de mai sus prezintฤ crearea tipului SUB. Acesta conศine toศi membrii ศi atributele din tipul de obiect pฤrinte.
Exemplu 1: รn exemplul de mai jos, folosim proprietatea de moศtenire pentru a insera o รฎnregistrare cu ID-ul managerului โ1002โ pentru รฎnregistrarea respectivฤ (โRRRโ, 1007, 20000). Executฤm programul รฎn urmฤtorii paศi.
- Pasul 1: Creaศi tipul SUPER.
- Pasul 2: Creaศi tipul ศi corpul SUB.
- Pasul 3: Creaศi un bloc anonim pentru a apela tipul SUB.
Pasul 1) Creaศi tipul SUPER sau tipul Pฤrinte.
Captura de ecran de mai jos aratฤ super-tipul emp_object creat cu clauza NOT FINAL.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50), p_salary NUMBER)RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records)NOT FINAL; /
Code Explicaลฃie:
- Code liniile 1-9: Se creeazฤ tipul de obiect โemp_objectโ cu 4 atribute ศi 3 membri. Acesta conศine definiศia unui constructor cu doar 3 parametri. A fost declarat ca โNOT FINALโ, deci este un tip pฤrinte.
Pasul 2) Creaศi tipul SUB sub tipul SUPER.
Captura de ecran de mai jos aratฤ tipul moศtenit sub_emp_object ศi corpul sฤu รฎn curs de creare.
CREATE OR REPLACE TYPE sub_emp_object UNDER emp_object (default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr); / CREATE OR REPLACE TYPE BODY sub_emp_object AS MEMBER PROCEDURE insert_default_mgr IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; END; /
Code Explicaลฃie:
- Code liniile 10-13: Crearea atributului โsub_emp_objectโ ca tip moศtenit cu un atribut suplimentar โdefault_managerโ ศi o declaraศie de procedurฤ membru.
- Code linia 14: Crearea corpului pentru tipul de obiect moศtenit.
- Code liniile 16-21: Definirea procedurii membre care insereazฤ รฎnregistrฤri รฎn tabelul 'emp' cu valorile din tipul de obiect SUPER, cu excepศia valorii manager. Pentru valoarea managerului, se utilizeazฤ 'default_manager' din tipul SUB.
Pasul 3) Crearea unui bloc anonim pentru apelarea tipului SUB.
Captura de ecran de mai jos prezintฤ blocul anonim care apeleazฤ tipul SUB ศi introduce ID-ul implicit al managerului.
DECLARE guru_emp_det sub_emp_object; BEGIN guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002); guru_emp_det.insert_default_mgr; COMMIT; END; /
Code Explicaลฃie:
- Code linia 25: Se declarฤ โguru_emp_detโ ca fiind de tipul โsub_emp_objectโ.
- Code linia 27: Iniศializarea obiectului cu constructorul implicit. Constructorul are 5 parametri (4 atribute din tipul PARENT ศi 1 atribut din tipul SUB). Ultimul parametru (1002) defineศte valoarea atributului default_manager.
- Code linia 28: Apelarea membrului โinsert_default_mgrโ pentru a insera รฎnregistrarea cu ID-ul implicit de manager transmis รฎn constructor.
Egalitatea obiectelor PL/SQL
Instanศele obiectelor care aparศin aceluiaศi tip de obiect pot fi comparate pentru egalitate. Pentru a face acest lucru, tipul de obiect are nevoie de o metodฤ specialฤ numitฤ metoda ORDER.
Aceastฤ metodฤ ORDER ar trebui sฤ fie o funcศie care returneazฤ un tip numeric. Acceptฤ doi parametri ca intrare (primul parametru: id-ul instanศei obiectului self; al doilea parametru: id-ul altei instanศe a obiectului).
ID-urile celor douฤ instanศe de obiect sunt comparate, iar rezultatul este returnat sub formฤ de numฤr.
- O valoare pozitivฤ indicฤ faptul cฤ instanศa obiectului SELF este mai mare decรขt cealaltฤ instanศฤ.
- O valoare negativฤ indicฤ faptul cฤ instanศa obiectului SELF este mai micฤ decรขt cealaltฤ instanศฤ.
- Zero indicฤ faptul cฤ instanศa obiectului SELF este egalฤ cu cealaltฤ instanศฤ.
- Dacฤ oricare dintre instanศe este nulฤ, funcศia returneazฤ null.
Captura de ecran de mai jos prezintฤ sintaxa funcศiei membru ORDER care trebuie inclusฤ รฎn corpul tipului pentru verificarea egalitฤศii.
CREATE TYPE BODY<object_type_name_ 1>AS OBJECT ( ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1) RETURN INTEGER IS BEGIN IF <attribute_name>parameter <attribute_name>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; . . ); /
Explicaศia sintaxei:
- Sintaxa de mai sus aratฤ funcศia ORDER care trebuie inclusฤ รฎn corpul tipului pentru verificarea egalitฤศii.
- Parametrul pentru aceastฤ funcศie ar trebui sฤ fie o instanศฤ de acelaศi tip de obiect.
- Funcศia poate fi apelatฤ ca โobj_instance_1.match(obj_instance_2)โ, iar aceastฤ expresie returneazฤ valoarea numericฤ afiศatฤ, unde obj_instance_1 ศi obj_instance_2 sunt instanศe ale tipului de obiect.
Exemplu 1: รn exemplul urmฤtor, comparฤm douฤ obiecte. Creฤm douฤ instanศe ศi comparฤm atributul โsalaryโ รฎntre ele. Facem acest lucru รฎn doi paศi.
- Pasul 1: Creaศi tipul ศi corpul obiectului.
- Pasul 2: Creaศi blocul anonim pentru a compara instanศele obiectului.
Pasul 1) Crearea tipului ศi corpului obiectului.
Capturile de ecran de mai jos prezintฤ specificaศia emp_object_equality ศi corpul acesteia, care defineศte funcศia ORDER ce comparฤ atributul salariu.
CREATE TYPE emp_object_equality AS OBJECT( salary NUMBER, ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER); /
CREATE TYPE BODY emp_object_equality AS ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER IS BEGIN IF salary<c.salary THEN RETURN -1; ELSIF salary>c.salary THEN RETURN 1; ELSE RETURN 0; END IF; END; END; /
Code Explicaลฃie:
- Code liniile 1-4: Se creeazฤ tipul de obiect โemp_object_equalityโ cu 1 atribut ศi 1 membru.
- Code liniile 6-16: Definirea funcศiei ORDER care comparฤ atributul โsalariuโ al instanศei SELF cu instanศa parametrului. Returneazฤ o valoare negativฤ dacฤ salariul SELF este mai mic, o valoare pozitivฤ dacฤ salariul SELF este mai mare ศi 0 dacฤ salariile sunt egale.
Code ieศire:
Tip creat
Pasul 2) Crearea blocului anonim pentru compararea instanศelor obiectului.
Captura de ecran de mai jos prezintฤ blocul anonim care comparฤ douฤ instanศe emp_object_equality dupฤ salariu.
DECLARE l_obj_1 emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_1:=emp_object_equality(15000); l_obj_2:=emp_object_equality(17000); IF l_obj_1.equals(l_obj_2)>0 THEN Dbms_output.put_line('Salary of first instance is greater'); ELSIF l_obj_1.equals(l_obj_2)<0 THEN Dbms_output.put_line('Salary of second instance is greater'); ELSE Dbms_output.put_line('Salaries are equal'); END IF; END; /
producศie
Salary of second instance is greater
Code Explicaลฃie:
- Code linia 20: Declararea obiectului โl_obj_1โฒ de tipul โemp_object_equalityโ.
- Code linia 21: Declararea obiectului โl_obj_2โฒ de tipul โemp_object_equalityโ.
- Code linia 23: Se iniศializeazฤ 'l_obj_1' cu valoarea salarialฤ '15000'.
- Code linia 24: Se iniศializeazฤ 'l_obj_2' cu valoarea salarialฤ '17000'.
- Code liniile 25-33: Afiศarea mesajului pe baza numฤrului returnat de funcศia ORDER.


















